运用socket select,recv 不能停止,一直接收数据

fs_te_ming 2012-06-21 04:00:06
小弟最近刚学习linux下网络问题,在练习select时,在accept之后,客户端发送了数据过来,服务端这边会重复的接收这部分数据,甚是迷惑。分数不多,请各位大侠指教
以下是部分输出结果:
select.
Incoming data.
received_data=touch /home/test/fun,i=5011
select.
Incoming data.
received_data=touch /home/test/fun,i=5012
select.
Incoming data.
received_data=touch /home/test/fun,i=5013
select.
Incoming data.
received_data=touch /home/test/fun,i=5014

以及客户服务端代码:
void ServerEntry()
{
fd_set readfds;
fd_set writefds;
fd_set exceptfds;
int retval;
int n=0;
int i=0;
char recv_cmd[20];
BOOLEAN bTerminate=FALSE;
BOOLEAN sockAccepted=FALSE;
socklen_t cli_len;
struct timeval timeout;
SOCKET listenSocket=0;
SOCKET sockfd2;
//printf("server entry.\n");
if (BindListenSocket(&listenSocket))
{
//printf("Bind successfully.\n");
if(listen(listenSocket,2)!=-1)
{
//printf("listen successfully.\n");
while(!bTerminate)
{
//printf("bTerminate.\n");
FD_ZERO (&readfds);

FD_SET (listenSocket,&readfds);
if(sockAccepted)
{
FD_SET(sockfd2,&readfds);
}
timeout.tv_sec = 5;
timeout.tv_usec = 0;
printf("select.\n");
retval = select(4100,&readfds,NULL,NULL,&timeout);
//printf("retval=%d\n",retval);
if ( retval == 0 )
{
printf("Select timeout.\n");
}
if(FD_ISSET(listenSocket,&readfds))
{
printf("Connection comming.\n");
BZERO((struct sockaddr_in *)&cli_addr,sizeof(cli_addr));
cli_len = sizeof (cli_addr);
sockfd2 = accept(listenSocket,(struct sockaddr *)&cli_addr,&cli_len);
if (sockfd2 < 0)
{
printf("Accept:accept failed.\n");
bTerminate=TRUE;
}
sockAccepted=TRUE;
}
//printf("Checking incoming data.\n");
if(sockAccepted)
{
if(FD_ISSET(sockfd2,&readfds))
{
printf("Incoming data.\n");
n=recv(sockfd2,recv_cmd,sizeof(recv_cmd),0);
if (n < 0)
printf("recv():receive from socket error.\n");
else
printf("received_data=%s,i=%d\n",recv_cmd,i);
system(recv_cmd);
i++;
}
}
//printf("Another loop.\n");
}
}
//printf("end server.\n");
close(listenSocket);
}
}

void ClientEntry()
{
int n=0;
int send_size;
char send_cmd[20];
sockfd=socket(AF_INET,SOCK_STREAM,0);
if (sockfd < 0)
printf("Socket():Open socket error.\n");
BZERO ( (struct sockaddr_in*) &serv_addr, sizeof (serv_addr) );
serv_addr.sin_family=AF_INET;
serv_addr.sin_port = htons ((short)18018);
serv_addr.sin_addr.s_addr=inet_addr("192.168.1.73");
if (connect (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr) ) < 0)
printf("Connect():connect socket error.\n");
BZERO (send_cmd, sizeof(send_cmd));
sprintf(send_cmd,"%s","touch /home/test/fun");
printf("%s\n",send_cmd);
send_size=sizeof(send_cmd);
n=send(sockfd,send_cmd,send_size,0);

}
...全文
407 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
fs_te_ming 2012-06-21
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

C/C++ code

void ServerEntry()
{
<snip>
n=recv(sockfd2,recv_cmd,sizeof(recv_cmd),0);
if (n < 0)
printf("recv():receive from socket error.\n");
else
printf("received_data=%s,i=%d\n",recv_cmd,i);


……
[/Quote]

才看到回复,现在明白了,已经改好了,谢谢各位
fs_te_ming 2012-06-21
  • 打赏
  • 举报
回复
我刚才改了下,在客户端send结束后,加了下面两句,服务端还是会一直接收
shutdown(sockfd,SHUT_RDWR);
close(sockfd);

然后我又改了下服务端的代码:
if (n <= 0)
printf("recv():receive from socket error.\n");
得到的结果为:
Incoming data.
recv():receive from socket error.
select.
Incoming data.
recv():receive from socket error.
select.
Incoming data.

这说明在接收了客户端的数据之后,recv接收的一直都是长度为0的数据

这个问题可以改一下解决了,但还是不太明白,为什么服务端这边会提示一直有数据在接收(长度却为0)?
mtyy110 2012-06-21
  • 打赏
  • 举报
回复

void ServerEntry()
{
<snip>
n=recv(sockfd2,recv_cmd,sizeof(recv_cmd),0);
if (n < 0)
printf("recv():receive from socket error.\n");
else
printf("received_data=%s,i=%d\n",recv_cmd,i);


客户端已经死掉了,连接被关闭,所以recv返回0,于是进入else分支
qq120848369 2012-06-21
  • 打赏
  • 举报
回复
if (n < 0)
printf("recv():receive from socket error.\n");
else
printf("received_data=%s,i=%d\n",recv_cmd,i);
system(recv_cmd);
i++;

判断一下n == 0, 然后close掉。
modicum_lf 2012-06-21
  • 打赏
  • 举报
回复

recv返回值 0 表示连接中断 你在client端是不是该close 这个socket

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧