Поясню, более конкретно, чего я хочу. Может будут другие варианты, как это реализовать. Сервер запускается в отдельном потоке, который создает загружаемый плагин. При выгрузке плагина, хочется, чтобы сервер корректно завершал свою работу. В блокирующем режиме сервер вызывает accept и управление к нему не возвращается (пока кто-то не создаст соединение). Была идея перед вызовом accept сделать цыкл в котором с помощью select определять попытку соединения, но ничего не получилось. Потом попробовал использовать неблокирующий сокет. Вот код сервера:
| Код | void DoServer() { SOCKET lSck,cSck; SOCKADDR_IN sin; int nlen; if((lSck=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET){ Error("ERROR: Failed to create listening socket %d"); return; } nlen=1; if(ioctlsocket(lSck,FIONBIO,&nlen)==SOCKET_ERROR)AddLog("Error switch in nonblock mode"); else AddLog("Socket in nonblock mode"); sin.sin_family=AF_INET; sin.sin_port=htons(Port); sin.S_addr=INADDR_ANY; if(bind(lSck,&sin,sizeof(sockaddr))!=0){ Error("ERROR: Failed to bind() listening socket %d"); return; } if(listen(lSck,5)!=0){ Error("ERROR: Failed to listen() socket %d"); return; } do{ nlen=sizeof(sockaddr); while((cSck=accept(lSck,&sin,&nlen))==-1){ if(WSAGetLastError()!=10035){ Error("ERROR - accept() failed %d"); return; } Sleep(0); if(processtread==FALSE)return; } nlen=sizeof(sockaddr); getpeername(cSck,&sin,&nlen); InputMsg(cSck); closesocket(cSck); }while(processtread); }
|
Все отрабатывает как надо, кроме завершения работы - зависает на вызова WSACleanup(). Вот код главного потока:
| Код | void MainThread(dword i) { WSADATA WSAData; runthread=TRUE; AddLog("Start Server Thread"); if(WSAStartup(0x202,#WSAData)!=0)Error("WSAStartup() failed with error code %d"); else DoServer(); WSACleanup(); AddLog("Close Server Thread"); runthread=FALSE; }
|
|