Просмотр полной версии : Как дождаться завершения функции
stinkybob
17.04.2010, 03:44
День добрый столкнулся с такой проблемой... у меня есть сокет сервер на си и клиент на флеше соответсвенно..
когда flash'ка коннектиться к серверу она должна послать три команды:
private function sendHello(){
toSend("Hello_Server");
toSend("cmd1");
toSend("cmd2");
}
public function toSend(commands:String):void {
tocommand=new ByteArray();
tocommand.writeMultiByte(commands,"UTF-8");
socket.writeBytes(tocommand);
socket.flush();
}
проблема в том что видимо все это очень быстро происходит и данные сливаются и сервер вместо
HELLO_SERVER
CMD1
CMD2
получает
HELLO_SERVER
CMD1CMD2
попытался использовать таймер, получилось но к сожалению в данной задумке я не могу его юзать так как факторов много.. плохое соединение, плохой комп, и результат работы таймера может быть разным... Помогите плз, как сделать так чтобы он отправлял команду только после того как отправил предидущую, т.е. выполнял функцию только после того как она выполнилась полностью
Заранее спасибо!
1. Не понятно зачем таким странным способом посылать UTF-8 строки.
2. TCP все равно будет отправлятся пакетами, максимум - сколько влезло, столько влезло, что вы можете сделать, это дождаться сообщения об обработке предыдущей команды и потом послать следующую. Но это будет не рционально по времени и затраченым усилиям, лучше записывайте команды так, чтобы они либо были фиксированого размера, либо была однозначная логика в их размере, либо просто определенный символ-разделитель между ними.
gloomyBrain
17.04.2010, 12:08
Какого бы размера ни было одно сообщение, склеиваться на клиенте они точно не могут - мне данный баг не повторить никак. И, да, еть такой метод:
socket.writeUTF(string:String);
iflamberg
17.04.2010, 13:40
ты такой баг не повторишь на локалхосте. А на сервере с медленным пингом - легко.
gloomyBrain
17.04.2010, 16:11
Вот как раз наоборот.
Чем больше пинг, тем больше время между двумя пакетами (меньше вероятность склейки(хотя - откуда ей тут быть?)).
В любом случае, flush() вызывается каждый раз, значит от флеша данные уходят вполне дискретными кусочками. Так что, на мой взгляд, беда в серверной части
Да нет, дело не в этом, флеш же не сам обеспечивает реализацию TCP, flush() просто значит очистить данные которые были сейчас записаны в сокет и послать их, а уже как они пошлются - это решает програма, которая непосредственно TCP реализует. Захочет - подождет пока максимальный размер пакета наберется, не захочет - опправит так. Т.е. предположим, что размер пакета 100 байт, в первый раз флеш записал 70 байт + flush() програма обеспечивающая соединение увидела, что данных не достаточно, и стала в режим ожидания - если в течение секунды не прийдет еще 30+ байт, пошлет, как есть, а если прийдет, то добавит эти 30 байт, и если остаток не дотягивает до 100, снова встанет на таймер. Ну, это так, очень умозрительно, но фишка в том, что TCP обязан отправлять данные по одному пакету и всегда ждать подтверждения о получении, поэтому он не может просто по желанию взять и послать произвольное количество информации.
iflamberg
17.04.2010, 18:29
Tcp/ip вообще не отсылает следующий пакет, пока не прийдет сообщение о доставке предыдущего (если не отключен принудительно алгоритм Нейгла).
stinkybob
17.04.2010, 23:04
что делать то :D
iflamberg
17.04.2010, 23:08
wvxvw тебе вторым постом всё уже написал
stinkybob
17.04.2010, 23:24
1. Не понятно зачем таким странным способом посылать UTF-8 строки.
а каким способои отправлять?
TCP все равно будет отправлятся пакетами, максимум - сколько влезло, столько влезло, что вы можете сделать, это дождаться сообщения об обработке предыдущей команды и потом послать следующую.
сервер отправляет ответ только полсе нескольких команд, я посылаю ему команду потом параметры команды в 2-3 сообщениях
лучше записывайте команды так, чтобы они либо были фиксированого размера, либо была однозначная логика в их размере, либо просто определенный символ-разделитель между ними.
ок, вот у меня есть функция toSend(value) я пишу ее три раза чтобы отправить 3 команды как мне сделать так чтобы каждая команда была строго определенного размера(разного) и желательно с деапозоном от 5 до 7 символов скажем, сиволы разделители и переходы на другие стороны юзать незя в моем случае
определенный размер != разный размер...
writeUTF / writeUTFBytes
stinkybob
18.04.2010, 18:05
добавил ф функцию величину
function toSend(commands:String, len:int):void {
if(commands.length==len) {
socket.writeUTFBytes(commands);
socket.flush();
}
}
function sendHello() {
toSend("Hello_Server", 12);
toSend("cmd1", 4);
toSend("cmd2", 4);
}
все равно тоже самое
ОК, пример:
предположим, вы установите правило, что команда должна быть всегда 4 байта - в таком случае ее всегда можно записать как один интеджер, и не важно в как и сколько раз вы вызовете flush() - если есть достаточно байт, вы прочитаете вашу команду, если нет - подождете, пока не получите достаточно байт.
Псевдокод:
// client
void WriteCommand( Command c ) {
socket.writeInt( CommandToInt( c ) );
}
// server
Command ReadCommand() {
if ( socket.bytesAvailable > 3 ) return IntToCommand( socket.readInt() );
return null;
}
Конечно, дальше можно оптимизировать, так, например, шансов, что команд будет аж 0xFFFFFFFF мало, скорее всего их будет не больше 0хFF, в таком случае можно использовать readByte() / writeByte() ну и так далее.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.