SOCKET API TCP连接,客户端第二次请求服务器无响应

garylau 2008-01-10 11:03:07
用SOCKET API开发C/S架构程式,Client和Server的处理流程如下:

Client: 创建线程 -> WSAStartup -> socket -> bind -> connect -> send -> sleep(500ms) -> send

Server: 创建Listen线程 -> WSAStartup -> socket -> bind -> listen -> accept -> 创建Comm线程 -> recv -> Terminate Comm线程 -> accept

现在第一次accept可以接收,但客户端第二次send的时候服务端的accept没有反应。

我试过在第一次send之后客户端执行了closesocket和WSACleanup,第二次能够收到,但是会有错误提示(还没弄明白是什么错误)。

请问每send一次都要closesocket或者WSACleanup(还是两个都要)一次吗(TCP协议)?close了之后是否重新需要建立一次?

谢谢!
...全文
739 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
garylau 2008-01-16
  • 打赏
  • 举报
回复
结贴!多谢!
garylau 2008-01-15
  • 打赏
  • 举报
回复
人工再顶,没有热心的人能帮帮忙吗?现在基本上可以确定是client端的问题。。就是找不到在哪里出错。
mabaoyes 2008-01-15
  • 打赏
  • 举报
回复
sock = socket(AF_INET,SOCK_DGRAM,0); //UDP
sock = socket(AF_INET,SOCK_STREAM,0); //TCP
mabaoyes 2008-01-15
  • 打赏
  • 举报
回复
不知道问题到底是出在服务端还是客户端,我现在客户端改为send一次之后就Terminate掉线程(socket也cleanup掉了),然后再创建线程send就好了,跟UDP模式有点类似了。。。
--------------------------------------------------------
socket 要设置 UDP模式/TCP模式 默认是TCP.
TCP 要维持连接的. 如果关闭,再发要重新连接。
garylau 2008-01-14
  • 打赏
  • 举报
回复
自己顶一下
garylau 2008-01-11
  • 打赏
  • 举报
回复
不知道问题到底是出在服务端还是客户端,我现在客户端改为send一次之后就Terminate掉线程(socket也cleanup掉了),然后再创建线程send就好了,跟UDP模式有点类似了。。。

楼上两位好像说的都是指我服务端有问题
garylau 2008-01-11
  • 打赏
  • 举报
回复
非常感谢痞子酷和酱哥的解答!

根据僵哥的意思是整个对话过程中都不需要closesocket或者WSACleanup,对吗?

而我理解SOCKET变量实际上就是一个对应系统中绑定的套接字表格的标识(int),为了节省代码,我自定义了一个TMySocket的类(即包含了服务端方法,也包含客户端方法),里面有两个SOCKET成员变量,一个是主的Socket,一个是Accept_Socket,accept(Socket, ...)不为INVALID_SOCKET之后,将结果传给Accpet_Socket。

在调用TMySocket的程式里,Listen线程调用Accept()函数(自定义的),做法就是上面说的把接收到的SOCKET变量传到类内部的变量Accept_Socket,然后创建Comm线程,再实例一个TMySocket变量,把第一个实例里面的Accept_Socket又传到新实例里面的主Socket,最后调用TMySocket内部的方法处理。新建实例中的Socket变量没有经过creat,bind之类的过程,因为我认为之前accept接收的这个Accept_Socket已经在系统里面注册了

可是结果就是,第一次接收没有问题,第二次就一直挂起在Accept()那里,接收不到新的消息。

说得很复杂,其实我就是为了图省事,把所有的方法做到一个类里面,不知道这样的思路有没有错误?如果没有的话可能是某些小的环节有遗漏,再慢慢查找。

恳请两位大侠再次指点迷津!多谢多谢!
r3624 2008-01-10
  • 打赏
  • 举报
回复
是否线程还没有处理完,单纯的sleep(500)不保险吧,server端执行完毕后返回一个消息如何
garylau 2008-01-10
  • 打赏
  • 举报
回复
我想在同一个socket连接里面实现c/s对话,请问选择TCP协议可以实现嘛?我现在的做法是客户端不停while( !Terminated ) + Suspend等待,WSAAsyncSelect接收服务端答复然后再Resume,不知道有没有更好的方法没有?(这个方法看起来很笨)。。。
僵哥 2008-01-10
  • 打赏
  • 举报
回复
请问每send一次都要closesocket或者WSACleanup(还是两个都要)一次吗(TCP协议)?close了之后是否重新需要建立一次?
==============
Send可以是无数次,直到网络出现错误,或者对方关闭,或者你自己需要关闭,才closesocket

WSAStartup是为使用网络而进行资源的准备
WSACleanup是释放网络资源
这两个的调用应该在一整个需要使用网络的过程的前和后。中途不需要。也就是:
需要使用网络->WSAStartup->开始使用网络...网络使用完毕->WSACleanup
僵哥 2008-01-10
  • 打赏
  • 举报
回复
建议楼主先看看基础的网络编程。

accept所使用的参数socket只能是那个原来在listen的socket.

客户端与服务器的对应(完全由客户端发送,而无须应答模式):
客户端:connect->Send->Send...->CloseSocket
服务器:Accept->Recv->Recv...->CloseSocket

客户端与服务器的对应(一问一答模式):
客户端:connect->Send->Send->Waiting for Recv->Recv...->CloseSocket
服务器:Accept->Recv->Recv->Process Data->Send...->CloseSocket
痞子酷 2008-01-10
  • 打赏
  • 举报
回复
Client: 创建线程 -> WSAStartup -> socket -> bind -> connect -> send -> sleep(500ms) -> send

Server: 创建Listen线程 -> WSAStartup -> socket -> bind -> listen -> accept -> 创建Comm线程 -> recv -> Terminate Comm线程 ->close(clientsoketid) -> accept
r3624 2008-01-10
  • 打赏
  • 举报
回复
哦这样那 sleep好像就没什么用啊

你是用bcb开发的么?我以前做过socket的东西,都是connect之前先closesocket下,保险
garylau 2008-01-10
  • 打赏
  • 举报
回复
楼上说的线程是指Server还是Client? Server在收到消息后会马上发回一条信息,而客户端在接收到之后则通知线程Resume,可是当执行完第二个send的时候,服务端没有收到消息。

而第二个send之前插入一个closesocket和wsacleanup服务端就可以收到了,不是很懂closesocket是不是要跟connect对应?就像new跟delete一样?

谢谢!

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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