Linux select的问题
问题描述如下:
客户端在有数据发送时,调用connect(...)连接客户端,然后发送数据,发送完成后。马上断开。为此服务器(为Linux RH9)端采用select模型。但程序测试的时候发现只在客户端第一次连接的时候能否接受到数据(select函数有返回)。第二次连接及以后的连接服务器(select函数无返回)。代码如下,大家帮我看下..
【Server端】
void mod_sec_log_thread(void)
{
trace_log("enter mod_sec_log htread....", 9);
struct sockaddr_in address;
int sockListen = socket(AF_INET, SOCK_STREAM, 0);
int tmpSocket;
int cirSocket;
int nSelectRet = 0;
int nCircle = 0;
int nRecv = 0;
int comSockArray[MAX_SOCKET_ARRAY];
int nCurrentConnection = 0;
char szSockRecvBuf[MAX_int_BUF];
struct sockaddr_in tmpAddr;
int nAddressLen = sizeof(struct sockaddr_in);
int address_len = 0;
if ( -1 == sockListen )
{
trace_log("Create ModSecurity List Socket Error", 9);
return;
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_ANY);
address.sin_port = htons(LOCAL_LISTEN_PORT);
address_len = sizeof(address);
if ( -1 == bind(sockListen, &address, address_len))
{
trace_log("error bind...", 9);
return;
}
if (listen(sockListen, 5) == -1)
{
trace_log("error Listen...", 9);
return;
}
fd_set fdread;
FD_ZERO(&fdread);
FD_SET(sockListen,&fdread);
reset_socket_array(comSockArray, MAX_SOCKET_ARRAY);
// just MAX_SOCKET_ARRAY - 1 can comunicate
add_socket_array(sockListen, comSockArray, MAX_SOCKET_ARRAY);
nCurrentConnection++;
while ( 1 )
{
trace_log("enter mod_log...", 9);
int maxSock = get_max_socket_array(comSockArray, MAX_SOCKET_ARRAY);
printf("maxSock: %d\n CurrentConnection: %d\n", maxSock, nCurrentConnection);
nSelectRet = select(maxSock + 1,
&fdread,
NULL,
NULL,
NULL);
trace_log("after select.......................", 9);
if ( nSelectRet <= 0 )
{
continue;
}
// new connection
if ( FD_ISSET(sockListen, &fdread) )
{
trace_log("a connection is comming....", 9);
if ( nCurrentConnection > MAX_SOCKET_ARRAY )
{
trace_log("too much connections...", 9);
}
else
{
trace_log("add to socket array....", 9);
printf("current connection:%d\n", nCurrentConnection);
tmpSocket = accept(sockListen, &tmpAddr, &nAddressLen);
printf("new socket: %d\n", tmpSocket);
FD_SET(tmpSocket, &fdread);
add_socket_array(tmpSocket, comSockArray, MAX_SOCKET_ARRAY);
// add connection count
nCurrentConnection++;
}
}
// communicate event
for ( nCircle = 0; nCircle < MAX_SOCKET_ARRAY; nCircle++ )
{
cirSocket = comSockArray[nCircle];
if ( FD_ISSET(cirSocket, &fdread) && cirSocket != sockListen)
{
nRecv = recv(cirSocket, szSockRecvBuf, MAX_int_BUF, 0);
if ( nRecv < 0 )
{
trace_log("recv Error...", 9);
continue;
}
// client closeSocket
if ( 0 == nRecv )
{
trace_log("Client closeSocket....", 9);
FD_CLR(cirSocket, &fdread);
clr_socket_array(cirSocket, comSockArray, MAX_SOCKET_ARRAY);
nCurrentConnection--;
continue;
}
else
{
szSockRecvBuf[nRecv] = '\0';
trace_log("recved somthing...", 9);
trace_log(szSockRecvBuf, 9);
}
}
}
}
}
【Client端】 客户端分别写了3个函数(连接、发送、关闭)。 单线程调用这三方函数
static int sock;
int ConnectToNPServer(const char * szIP,int nPort)
{
struct sockaddr_in server_addr;
sock = socket(AF_INET, SOCK_STREAM, 0);
if( sock < 0 )
{
return 1;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(nPort);
server_addr.sin_addr.s_addr = inet_addr(szIP);
memset(server_addr.sin_zero,0,8);
if (connect(sock, (struct sockaddr *) & server_addr,sizeof (struct sockaddr)) == -1)
{
sock = -1;
return 1;
}
return 0;
}
int SendBuf(const char* buf, int size)
{
if( sock < 0)
{
return 1;
}
else
{
if(send(sock,buf,strlen(buf),0) == -1)
{
cout << "Error Send" << WSAGetLastError() << endl;
return 1;
}
return 0;
}
}
void DisConnect()
{
if( sock < 0)
{
return;
}
closesocket(sock);
}
////////发送部分:
DWORD MyThreadFunction1( LPVOID lpParam )
{
for(int i = 0; i < 10;i++)
{
ConnectToNPServer(DES_IP_ADDRESS, DES_PORT);
SendBuf("0123456789--------------------------------------------", 30);
DisConnect();
Sleep(5000);
}
return 0;
}