服务器套接字只能连接几次(Winsock C+;+;) 我试图在C++中编写一个服务器Winsock,以允许从PHP客户端代码连接。PHP将从服务器请求数据,接收数据,然后关闭连接。但是,经过2-3次连接后,当PHP再次请求时,它挂起在socket_read(),页面继续加载,并且服务器没有收到FD_ACCEPT事件。是否因为等待时间的关系,连接尚未关闭?任何关于代码改进的建议都很好 SOCKET s; SOCKADDR_IN from; int fromLen = sizeof(from); int port = 1111; int listenOnPort(int portNo) { WSAData w; int error = WSAStartup(0x0202, &w); // fill in wsa info if(error) { printError(5); return 0; } if(w.wVersion != 0x0202) { printError(6); WSACleanup(); return 0; } SOCKADDR_IN addr; SOCKET client; addr.sin_family = AF_INET; addr.sin_port = htons(portNo); addr.sin_addr.s_addr = htonl(INADDR_ANY); s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(s == INVALID_SOCKET) { printError(7); return 0; } BOOL bOptVal = TRUE; int bOptLen = sizeof (BOOL); if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&bOptVal, bOptLen) == SOCKET_ERROR) { printError(12); return 0; } if(bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR) { printError(8); return 0; } if( listen(s, 1) == SOCKET_ERROR ) //start listening { printError(13); return 0; } //WSAAsyncSelect(s, hwnd, 1045, FD_READ | FD_CONNECT | FD_CLOSE | FD_ACCEPT); cout << "Ready to accept connection, listening on port " << portNo << endl; CreateThread(0,0, &listenForEvents, NULL, 0, 0); //listenForEvents(); return 1; //ok } DWORD WINAPI listenForEvents(void* lp) { HANDLE sockEv=CreateEvent(NULL,TRUE,FALSE,NULL); if(WSAEventSelect(s,sockEv,FD_ACCEPT|FD_CONNECT| FD_READ | FD_CLOSE )==SOCKET_ERROR) printError(9); for(;;) { if(WSAWaitForMultipleEvents(1,&sockEv,FALSE,INFINITE,FALSE)!=WSA_WAIT_EVENT_0) printError(10); WSANETWORKEVENTS wsaEvents={0}; if(WSAEnumNetworkEvents(s,sockEv,&wsaEvents)==SOCKET_ERROR) printError(11); if((wsaEvents.lNetworkEvents & FD_ACCEPT)==FD_ACCEPT) { SOCKET tempSock = accept(s, (struct sockaddr*) &from, &fromLen); s = tempSock; //switch our old socket to the new one char acceptAddr[100]; char* msg = "Connnection from [%s] accepted."; //sprintf(acceptAddr, msg, inet_ntoa(from.sin_addr) ); sprintf_s(acceptAddr, strlen(msg) + 100, msg, inet_ntoa(from.sin_addr)); cout << acceptAddr << endl; hasClient = true; } else if((wsaEvents.lNetworkEvents & FD_READ) == FD_READ){ char buffer[1000]; memset(buffer, 0, sizeof(buffer)); recv(s, buffer, sizeof(buffer)-1, 0); receiveAction(string(buffer)); //cout << buffer << endl; } else if((wsaEvents.lNetworkEvents & FD_CLOSE) == FD_CLOSE){ shutdown(s, SD_BOTH ); closesocket(s); cout << "socket closed" << endl; startServer(); // start server again return 0; } else if(wsaEvents.lNetworkEvents==0) { printError(14); cout << "lNetworkEvents==0" << endl; } } } void startServer(){ listenOnPort(port); }
最后,它成功了,我对winsock函数、流等还不是很了解。这是有效的。关键是让侦听器套接字保持活动状态,然后将客户机/接受的套接字存储在另一个位置服务器套接字只能连接几次(Winsock C+;+;) 我试图在C++中编写一个服务器Winsock,以允许从PHP客户端代码连接。PHP将从服务器请求数据,接收数据,然后关闭连接。但是,经过2-3次连接后,当PHP再次请求时,它挂起在socket_read(),页面继续加载,并且服务器没有收到FD_ACCEPT事件。是否因为等待时间的关系,连接尚未关闭?任何关于代码改进的建议都很好 SOCKET s; SOCKADDR_IN from; int fromLen = sizeof(from); int port = 1111; int listenOnPort(int portNo) { WSAData w; int error = WSAStartup(0x0202, &w); // fill in wsa info if(error) { printError(5); return 0; } if(w.wVersion != 0x0202) { printError(6); WSACleanup(); return 0; } SOCKADDR_IN addr; SOCKET client; addr.sin_family = AF_INET; addr.sin_port = htons(portNo); addr.sin_addr.s_addr = htonl(INADDR_ANY); s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(s == INVALID_SOCKET) { printError(7); return 0; } BOOL bOptVal = TRUE; int bOptLen = sizeof (BOOL); if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&bOptVal, bOptLen) == SOCKET_ERROR) { printError(12); return 0; } if(bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR) { printError(8); return 0; } if( listen(s, 1) == SOCKET_ERROR ) //start listening { printError(13); return 0; } //WSAAsyncSelect(s, hwnd, 1045, FD_READ | FD_CONNECT | FD_CLOSE | FD_ACCEPT); cout << "Ready to accept connection, listening on port " << portNo << endl; CreateThread(0,0, &listenForEvents, NULL, 0, 0); //listenForEvents(); return 1; //ok } DWORD WINAPI listenForEvents(void* lp) { HANDLE sockEv=CreateEvent(NULL,TRUE,FALSE,NULL); if(WSAEventSelect(s,sockEv,FD_ACCEPT|FD_CONNECT| FD_READ | FD_CLOSE )==SOCKET_ERROR) printError(9); for(;;) { if(WSAWaitForMultipleEvents(1,&sockEv,FALSE,INFINITE,FALSE)!=WSA_WAIT_EVENT_0) printError(10); WSANETWORKEVENTS wsaEvents={0}; if(WSAEnumNetworkEvents(s,sockEv,&wsaEvents)==SOCKET_ERROR) printError(11); if((wsaEvents.lNetworkEvents & FD_ACCEPT)==FD_ACCEPT) { SOCKET tempSock = accept(s, (struct sockaddr*) &from, &fromLen); s = tempSock; //switch our old socket to the new one char acceptAddr[100]; char* msg = "Connnection from [%s] accepted."; //sprintf(acceptAddr, msg, inet_ntoa(from.sin_addr) ); sprintf_s(acceptAddr, strlen(msg) + 100, msg, inet_ntoa(from.sin_addr)); cout << acceptAddr << endl; hasClient = true; } else if((wsaEvents.lNetworkEvents & FD_READ) == FD_READ){ char buffer[1000]; memset(buffer, 0, sizeof(buffer)); recv(s, buffer, sizeof(buffer)-1, 0); receiveAction(string(buffer)); //cout << buffer << endl; } else if((wsaEvents.lNetworkEvents & FD_CLOSE) == FD_CLOSE){ shutdown(s, SD_BOTH ); closesocket(s); cout << "socket closed" << endl; startServer(); // start server again return 0; } else if(wsaEvents.lNetworkEvents==0) { printError(14); cout << "lNetworkEvents==0" << endl; } } } void startServer(){ listenOnPort(port); },php,c++,windows,sockets,winsock,Php,C++,Windows,Sockets,Winsock,最后,它成功了,我对winsock函数、流等还不是很了解。这是有效的。关键是让侦听器套接字保持活动状态,然后将客户机/接受的套接字存储在另一个位置 SOCKET sock[2]; SOCKADDR_IN from; int fromLen = sizeof(from); int port = 1111; int listenOnPort(int portNo) { WSAData w; int error = WSAStartup(0x0202, &w); // fil
SOCKET sock[2];
SOCKADDR_IN from;
int fromLen = sizeof(from);
int port = 1111;
int listenOnPort(int portNo)
{
WSAData w;
int error = WSAStartup(0x0202, &w); // fill in wsa info
if(error)
{
printError(5);
return 0;
}
if(w.wVersion != 0x0202)
{
printError(6);
WSACleanup();
return 0;
}
SOCKADDR_IN addr;
SOCKET client;
addr.sin_family = AF_INET;
addr.sin_port = htons(portNo);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
sock[0] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock[0] == INVALID_SOCKET)
{
printError(7);
return 0;
}
BOOL bOptVal = TRUE;
int bOptLen = sizeof (BOOL);
if(setsockopt(sock[0], SOL_SOCKET, SO_REUSEADDR, (char *)&bOptVal, bOptLen) == SOCKET_ERROR)
{
printError(12);
return 0;
}
if(bind(sock[0], (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
{
printError(8);
return 0;
}
if( listen(sock[0], 1) == SOCKET_ERROR ) //start listening
{
printError(13);
return 0;
}
//WSAAsyncSelect(sock[0], hwnd, 1045, FD_READ | FD_CONNECT | FD_CLOSE | FD_ACCEPT);
cout << "Ready to accept connection, listening on port " << portNo << endl;
CreateThread(0,0, &listenForEvents, NULL, 0, 0);
//listenForEvents();
return 1; //ok
}
DWORD WINAPI listenForEvents(void* lp)
{
HANDLE sockEv[2];
sockEv[0]=CreateEvent(NULL,TRUE,FALSE,NULL);
sockEv[1]=CreateEvent(NULL,TRUE,FALSE,NULL);
if(WSAEventSelect(sock[0],sockEv[0],FD_ACCEPT|FD_CONNECT|FD_CLOSE )==SOCKET_ERROR)
printError(9);
for(;;) {
int index = WSAWaitForMultipleEvents(2,sockEv,FALSE,INFINITE,FALSE);
//if(index != WSA_WAIT_EVENT_0)
// printError(10);
index -= WSA_WAIT_EVENT_0;
WSANETWORKEVENTS wsaEvents={0};
if(WSAEnumNetworkEvents(sock[index],sockEv[index],&wsaEvents)==SOCKET_ERROR)
printError(11);
if((wsaEvents.lNetworkEvents & FD_ACCEPT)==FD_ACCEPT) {
sock[index+1]= accept(sock[index], (struct sockaddr*) &from, &fromLen);
//s = clientSock; //switch our old socket to the new one
if(WSAEventSelect(sock[index+1], sockEv[index+1], FD_READ|FD_CLOSE ) == SOCKET_ERROR)
{
printError(15);
}
char acceptAddr[100];
char* msg = "Connnection from [%s] accepted.";
//sprintf(acceptAddr, msg, inet_ntoa(from.sin_addr) );
sprintf_s(acceptAddr, strlen(msg) + 100, msg, inet_ntoa(from.sin_addr));
cout << acceptAddr << endl;
hasClient = true;
}
else if((wsaEvents.lNetworkEvents & FD_READ) == FD_READ){
char buffer[1000];
memset(buffer, 0, sizeof(buffer));
recv(sock[index], buffer, sizeof(buffer)-1, 0);
receiveAction(string(buffer));
}
else if((wsaEvents.lNetworkEvents & FD_CLOSE) == FD_CLOSE){
shutdown(sock[index], SD_BOTH );
closesocket(sock[index]);
if(getDebug())
{
cout << "socket closed" << endl;
}
//startServer(); // start server again
//return 0;
}
else if(wsaEvents.lNetworkEvents==0) {
printError(14);
cout << "lNetworkEvents==0" << endl;
}
}
}
插座插座[2];
SOCKADDR_从中输入;
int-fromLen=sizeof(from);
int端口=1111;
int-listenport(int-portNo)
{
WSAData w;
int error=WSAStartup(0x0202,&w);//填写wsa信息
如果(错误)
{
打印错误(5);
返回0;
}
如果(w.wVersion!=0x0202)
{
打印错误(6);
WSACleanup();
返回0;
}
地址中的SOCKADDR_;
套接字客户端;
addr.sin_family=AF_INET;
地址sin_端口=htons(端口号);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
sock[0]=套接字(自动网络、sock流、IPPROTO\u TCP);
if(sock[0]==无效的\u套接字)
{
打印错误(7);
返回0;
}
BOOL-bOptVal=TRUE;
int bOptLen=sizeof(布尔);
if(setsockopt(sock[0],SOL_SOCKET,SO_REUSEADDR,(char*)&bOptVal,bOptLen)=套接字错误)
{
打印错误(12);
返回0;
}
if(bind(sock[0],(LPSOCKADDR)&addr,sizeof(addr))==SOCKET\u错误)
{
打印错误(8);
返回0;
}
if(listen(sock[0],1)==SOCKET\u ERROR)//开始侦听
{
打印错误(13);
返回0;
}
//WSAAsyncSelect(sock[0],hwnd,1045,FD|u READ | FD|u CONNECT | FD|u CLOSE | FD|u ACCEPT);
库特
SOCKET sock[2];
SOCKADDR_IN from;
int fromLen = sizeof(from);
int port = 1111;
int listenOnPort(int portNo)
{
WSAData w;
int error = WSAStartup(0x0202, &w); // fill in wsa info
if(error)
{
printError(5);
return 0;
}
if(w.wVersion != 0x0202)
{
printError(6);
WSACleanup();
return 0;
}
SOCKADDR_IN addr;
SOCKET client;
addr.sin_family = AF_INET;
addr.sin_port = htons(portNo);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
sock[0] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock[0] == INVALID_SOCKET)
{
printError(7);
return 0;
}
BOOL bOptVal = TRUE;
int bOptLen = sizeof (BOOL);
if(setsockopt(sock[0], SOL_SOCKET, SO_REUSEADDR, (char *)&bOptVal, bOptLen) == SOCKET_ERROR)
{
printError(12);
return 0;
}
if(bind(sock[0], (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
{
printError(8);
return 0;
}
if( listen(sock[0], 1) == SOCKET_ERROR ) //start listening
{
printError(13);
return 0;
}
//WSAAsyncSelect(sock[0], hwnd, 1045, FD_READ | FD_CONNECT | FD_CLOSE | FD_ACCEPT);
cout << "Ready to accept connection, listening on port " << portNo << endl;
CreateThread(0,0, &listenForEvents, NULL, 0, 0);
//listenForEvents();
return 1; //ok
}
DWORD WINAPI listenForEvents(void* lp)
{
HANDLE sockEv[2];
sockEv[0]=CreateEvent(NULL,TRUE,FALSE,NULL);
sockEv[1]=CreateEvent(NULL,TRUE,FALSE,NULL);
if(WSAEventSelect(sock[0],sockEv[0],FD_ACCEPT|FD_CONNECT|FD_CLOSE )==SOCKET_ERROR)
printError(9);
for(;;) {
int index = WSAWaitForMultipleEvents(2,sockEv,FALSE,INFINITE,FALSE);
//if(index != WSA_WAIT_EVENT_0)
// printError(10);
index -= WSA_WAIT_EVENT_0;
WSANETWORKEVENTS wsaEvents={0};
if(WSAEnumNetworkEvents(sock[index],sockEv[index],&wsaEvents)==SOCKET_ERROR)
printError(11);
if((wsaEvents.lNetworkEvents & FD_ACCEPT)==FD_ACCEPT) {
sock[index+1]= accept(sock[index], (struct sockaddr*) &from, &fromLen);
//s = clientSock; //switch our old socket to the new one
if(WSAEventSelect(sock[index+1], sockEv[index+1], FD_READ|FD_CLOSE ) == SOCKET_ERROR)
{
printError(15);
}
char acceptAddr[100];
char* msg = "Connnection from [%s] accepted.";
//sprintf(acceptAddr, msg, inet_ntoa(from.sin_addr) );
sprintf_s(acceptAddr, strlen(msg) + 100, msg, inet_ntoa(from.sin_addr));
cout << acceptAddr << endl;
hasClient = true;
}
else if((wsaEvents.lNetworkEvents & FD_READ) == FD_READ){
char buffer[1000];
memset(buffer, 0, sizeof(buffer));
recv(sock[index], buffer, sizeof(buffer)-1, 0);
receiveAction(string(buffer));
}
else if((wsaEvents.lNetworkEvents & FD_CLOSE) == FD_CLOSE){
shutdown(sock[index], SD_BOTH );
closesocket(sock[index]);
if(getDebug())
{
cout << "socket closed" << endl;
}
//startServer(); // start server again
//return 0;
}
else if(wsaEvents.lNetworkEvents==0) {
printError(14);
cout << "lNetworkEvents==0" << endl;
}
}
}