Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.14.86] |
|
Сообщ.
#1
,
|
|
|
Проблема....
Нарисовал простинький TCP серврер. А он работает на один бок! Клиент к нему удачно присоединяется, передаёт данные и отсоединяется, а когда снова делает попытку подсоединения, то при коннекте происходит ошибка! Делаю всё как и раньше делал (когдато) а не работает! Уже пробовал шатдаунить.... А хотел то я всего то cdplayer удалённо с другой машины запускать.... Вот сервер: //server.cpp<br>#include <windows.h><br>#include <winsock.h><br>#include <shellapi.h><br><br><br>int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,<br> PSTR szCmdLine, int iCmdShow)<br>{<br> char buf[1000];<br><br> WSADATA WSAData;<br> int nRc=WSAStartup(0x0101,&WSAData);<br><br> SOCKET MyS = socket(AF_INET, SOCK_STREAM,0);<br> <br> sockaddr_in addr;<br> addr.sin_family = AF_INET;<br> addr.sin_port = htons(5151);<br> addr.sin_addr.s_addr=inet_addr("192.168.100.11");<br> if(bind(MyS,(LPSOCKADDR)&addr,sizeof(addr)) == SOCKET_ERROR)<br> {<br> return;<br> }<br> else{<br> if(listen(MyS,5) == SOCKET_ERROR)<br> {<br> return;<br> }<br><br> int nAddrLen=sizeof(sockaddr);<br> SOCKET In;<br> sockaddr Ot;<br> while(1){<br> In=accept(MyS,&Ot,&nAddrLen);<br> int Z=recv(In,buf,10,0);<br> shutdown(In,2);<br> closesocket(In);<br> if(Z>0){<br> if(buf[0]==0){break;}<br> else if(buf[0]==1){<br> ShellExecute(0,"open","cdplayer",0,0,0);<br> }<br> else if(buf[0]==2){<br> ShellExecute(0,"open","cdplayer",0,0,SW_SHOW);<br> }<br> else if(buf[0]==3){<br> ShellExecute(0,"open","cdplayer e:\\",0,0,SW_SHOW);<br> }<br> }<br> }<br> closesocket(MyS);<br> }<br>} а вот клиент: #include <windows.h><br>#include <winsock.h><br><br><br>int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,<br> PSTR szCmdLine, int iCmdShow)<br>{<br> char buf[1000];<br> WSADATA WSAData;<br> int nRc=WSAStartup(0x0101,&WSAData);<br><br> SOCKET MyS = socket(AF_INET, SOCK_STREAM,0);<br> <br> sockaddr_in addr;<br> addr.sin_family = AF_INET;<br> addr.sin_port = htons(5050);<br> addr.sin_addr.s_addr=inet_addr("192.168.100.70");<br> if(bind(MyS,(LPSOCKADDR)&addr,sizeof(addr)) == SOCKET_ERROR)<br> {<br> return;<br> }<br><br> MessageBox(0,"Connecting","Connect",0);<br> <br> sockaddr_in ServerAddr;<br> ServerAddr.sin_family = AF_INET;<br> ServerAddr.sin_port = htons(5151);<br> ServerAddr.sin_addr.s_addr=inet_addr("192.168.100.11");<br> if(connect(MyS,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr))== SOCKET_ERROR)<br> {<br> MessageBox(0,"No Connected","Connect",0);<br> return;<br> }<br> MessageBox(0,"Connected!","Connect",0);<br><br> buf[0]=3;<br> send(MyS,buf,1,0);<br> shutdown(MyS,2);<br> closesocket(MyS);<br><br>} [right][ Теги [сode][/сode] добавлены by Leprecon ][/right] |
Сообщ.
#2
,
|
|
|
Твой сервак пример того что любой сервак желательно делать многопоточным,
после обработки запроса пользователя у тебя программа подвешивается на бесконечном цикле while(1) { ... } он из него просто не выходит и listen с accpet у тебя могут вызваны только один раз, раздели на два потока один ждёт подключения а второй обрабатвает запрос. На худой конец сделай нормальный цикл, а то у тебя получилась одноразовая программа. |
Сообщ.
#3
,
|
|
|
Дык процесс виснет не в цикле....
Виснет на комманде accept() А главное что через несколько минут, снова соединяется! А многопоточность помоему решит только один вопрос - одновременное обсуживание N количество клиентов. Это похоже на какой-то таймаут... ...но что это за таймаут ??? |
Сообщ.
#4
,
|
|
|
Цитата old_lamer, 11.04.03, 11:37:39 Дык процесс виснет не в цикле.... Виснет на комманде accept() А главное что через несколько минут, снова соединяется! А многопоточность помоему решит только один вопрос - одновременное обсуживание N количество клиентов. Это похоже на какой-то таймаут... ...но что это за таймаут ??? Вообще TCP делает таймаут при закрытие если, остались блуждающие пакеты от последней передачи,тобишь сервак не получил сегмент подтверждения от клиента о закрытие соединения,. но время этого таймаута не превышает 30сек x 2 для BSD систем или 5 максимум для других. Но Windows свой TCP слизала с BSD посему наверное минута. |
Сообщ.
#5
,
|
|
|
Цитата ViSko, 11.04.03, 11:56:55 Вообще TCP делает таймаут при закрытие если, остались блуждающие пакеты от последней передачи,тобишь сервак не получил сегмент подтверждения от клиента о закрытие соединения,. но время этого таймаута не превышает 30сек x 2 для BSD систем или 5 максимум для других. Но Windows свой TCP слизала с BSD посему наверное минута. Да, где-то минуту или 2 я немогу подключиться снова, но ведь клиент разсоединяется правильно (или нет?) И помоему, неуверен (сейчас я дома а баг на работе остался), но помоему клиент не мог подключиться (ошибка) даже когда сианс связи идет с другим клиентом, а помоему, при вызове функции connect() клиент должен ожидать accept() на серваке. В любом случае я не понимаю таймаут с какой радости происходит?? |
Сообщ.
#6
,
|
|
|
Я твои проги сохранил посомтрю в чём там трабал, самому интересно стало
но вобще для отладки полезно использовать: netstat -a - выводи список активных TCP соединений + очень полезно,- пишет состояние сокета на данный момент. |
Сообщ.
#7
,
|
|
|
Цитата old_lamer, 11.04.03, 18:47:38 И помоему, неуверен (сейчас я дома а баг на работе остался), но помоему клиент не мог подключиться (ошибка) даже когда сианс связи идет с другим клиентом, а помоему, при вызове функции connect() клиент должен ожидать accept() на серваке. Я сегодня даже на работу пришел, проверить этот баг, и вот что я заметил: Когда я подсоединяюсь к серверу открывая для клиента тот же порт с которого я уже соединялся (проводил сеанс), то происходит ошибка подключения, но соединяясь с другого порта всё нормально. По логике вещей это похоже на таймаут при разорванном соединении... |
Сообщ.
#8
,
|
|
|
Осторожнее надо с shutdown а то твой клиент закрывает передачу и получения данных от сеокета, потом ты закрываешь соединения следовательно клиент не может отправить пакет закрытия серверу и тот после физического разрыва ждёт пакета CLOSE но ни хрена не получает.
|
Сообщ.
#9
,
|
|
|
Обе программы - пример того, как не надо писать сетевые приложения.
.... зачем тебе сдался bind в клиенте? connect уже сам создает запись в системе .... просто создай сокет и потом сделай connect, а если так хочешь оставить (что совсем не правильно) то поставь опцию REUSEADDR на сокет ........ ЗЫ: и еще imho такую конструкцию (вопрос - ответ) лучше на UDP строить ... ЗЫЫ: после shutdown(.., 2) но надо вызывать closesocket() (это совсем не обязательно); |