socket TCP连接 为什么recv()一直在接收啊?

jay_lee_1982 2008-10-25 01:37:43
我把孙鑫老师的TCP socket编程改了一下,不知道为什么,TCPServer端始终在接收字符串“This is lisi”,尽管TCPClient端只发送了一次,请高手指点,谢谢!!!
TCP Server 端源程序:
。。。。。。//加载套接字库(略)
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5);

SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"Welcome %s to http://www.sunxin.org",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
while(1)
{
char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
//closesocket(sockConn); 这里被我改掉了,本来是没有注释掉,所以接收了一次就关闭了
}

TCP Client端源程序:
。。。。。。//加载套接字库(略)
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

char recvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
send(sockClient,"This is lisi",strlen("This is lisi")+1,0);//这里只发送了一次,为什Server端一直在接收呢?

closesocket(sockClient);
WSACleanup();

是不是在Server端我没有用socket阻塞?还是什么原因呢?
...全文
1478 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
jay_lee_1982 2008-10-27
  • 打赏
  • 举报
回复
谢谢,我想再问一下,那我TCP SERVER怎么才能同时监听多个端口呢?(譬如两个或者更多),是不是就不能用while(1)来循环了啊?
pleasechangegreat 2008-10-27
  • 打赏
  • 举报
回复
while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"Welcome %s to http://www.sunxin.org",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);

char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
//closesocket(sockConn); 这里被我改掉了,本来是没有注释掉,所以接收了一次就关闭了
}

我最近也在搞SOCKET,你把accept那些语句放到while中比较好。
pleasechangegreat 2008-10-27
  • 打赏
  • 举报
回复
while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"Welcome %s to http://www.sunxin.org",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);

char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
//closesocket(sockConn); 这里被我改掉了,本来是没有注释掉,所以接收了一次就关闭了
}

我最近也在搞SOCKET,你把accept那些语句放到while中比较好。
用户 昵称 2008-10-27
  • 打赏
  • 举报
回复
你要想监听多个端口,可以accept之后起一个线程。
Yao-debo 2008-10-27
  • 打赏
  • 举报
回复
建议LZ选择好的SOCKET编程的书籍,如《LINUX网络编程》。。。
zencher 2008-10-27
  • 打赏
  • 举报
回复
WinSock的I/O机制有五种哦

select

WSAAsyncSelect

WSAEventSelet

重叠模型

完成端口

while( 1 )
{
reve( ... )
}
很不好用,如果基于窗口的话,用WSAAsyncSelect,建议楼主看看Windows网络编程,经典
zzultc 2008-10-26
  • 打赏
  • 举报
回复
char recvBuf[100];是个局部变量,记住一定要memset(0,...);
你出现这个问题的原因楼上的都解释过了。我再说得明白一点:
第一次while后,那个recvBuf已经失效,但是进入第二次while时候,重新申请的recvBuf和上个recvBuf恰好是同一地址,因为:根据你的程序情况,recvBuf应该在程序的栈空间里,在是那个一次while离开后,栈又平衡回到while前的地址了,而你的程序有没有初始化,于是.....
jinjin520 2008-10-26
  • 打赏
  • 举报
回复
while(1)
{
char recvBuf[100];
int val = recv(sockConn,recvBuf,100,0);
if(val != -1)
printf("%s\n",recvBuf);
recvBuf[0]='\0';
}
closesocket(sockConn);
你可以是是改成这样。。。
jay_lee_1982 2008-10-26
  • 打赏
  • 举报
回复
我现在把客户端的程序改成:
。。。。。。//加载套接字库(略):
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

char recvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
send(sockClient,"This is lisi",strlen("This is lisi")+1,0);//这里只发送了一次,为什Server端一直在接收呢?

//closesocket(sockClient);
//WSACleanup(); 把这两句注释起来了


可是,结果还是一样,服务器端还是始终在接收字符串“This is lisi”,为什么呀?
是不是因为我没有把recvbuf清空的原因?如果是的话,应该要怎么做才能清空呢?
jay_lee_1982 2008-10-25
  • 打赏
  • 举报
回复
那也就是说,recv一直在接收,即使客户端关闭了,它还是不会停的,只是如果没有接收到任何信息的话,就返回-1。对吧?
如果我把它改成:
while(1)
{
char recvBuf[100];
int val = recv(sockConn,recvBuf,100,0);
if(val != -1)
printf("%s\n",recvBuf);
//closesocket(sockConn); 这里被我改掉了,本来是没有注释掉,所以接收了一次就关闭了
}
这样的话,是不是就不会显示一直在接收字符串“This is lisi”了呢?

问题二:
另外,听说是不是还可以让recv阻塞的啊?只有当真正的数据进来以后,才会使程序从recv往下运行?是不是有这么一回事情啊?怎么做呢?
kevin0808 2008-10-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 missye1437 的回复:]
楼主,看来你是新手.

请注意,接收的模块不要和绑定的模块一起

也不要用while(1) 来判断,那样只能接收一次数据,甚至只能接收一个用户的数据.

那些教程太简单了.根本不能用.

我建议你买本网络编程的去看看

然后到我空间下载一个我编辑的实例吧! ^^ 祝你成功
[/Quote]

调用while(1)是没有问题的,这样才能不断地接受客户端的消息,否则需要用异步通知的方式
kevin0808 2008-10-25
  • 打赏
  • 举报
回复
这个网络程序没有问题,一直输出是因为你循环里的recvbuf没有清空
recv函数本来就是阻塞的,他所以能够返回时因为你客户端closesocket了
yize.link 2008-10-25
  • 打赏
  • 举报
回复
楼主,看来你是新手.

请注意,接收的模块不要和绑定的模块一起

也不要用while(1) 来判断,那样只能接收一次数据,甚至只能接收一个用户的数据.

那些教程太简单了.根本不能用.

我建议你买本网络编程的去看看

然后到我空间下载一个我编辑的实例吧! ^^ 祝你成功
Yao-debo 2008-10-25
  • 打赏
  • 举报
回复
在常规的网络环境下,TCP CLIENT端关闭后,服务器端的recv会一直返回-1;
while(1)
{
char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
//closesocket(sockConn); 这里被我改掉了,本来是没有注释掉,所以接收了一次就关闭了
}
你没有进行recv的返回值判断就调用printf,所以才让你误解了。
Conry 2008-10-25
  • 打赏
  • 举报
回复
socket默认就是阻塞,你客户端发送完了不关闭socket看看服务器是不是阻塞住了

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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