关于Winsock的几个问题。

my15y 2005-02-13 08:57:53
1) 在阻塞调用recv函数时候。我如何才能判断已经接收完了数据?
例如;
while((cc=recv(s,buf,sizeof(buf),0)) >0) {
..............
.............
}
但接收完数据后。他会在recv处阻塞。如果用select来做接收超时?

被断开连接后。立即跳出循环。。当然cc =0
我现在实在找不到其它方法来接收例如1mb的数据。循环调用recv来接收。接收完成后通知我。请教???
...全文
157 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
flyinair2000 2005-02-16
  • 打赏
  • 举报
回复
需等待应答才能送pass命令
----
你是如何知道对方应答的?通过block read()吗?
那么在asyncsocket中,只需要 override OnReceive(?) 就行了。
OnReceive 保证当有数据到达时,你会收到这个event.
my15y 2005-02-16
  • 打赏
  • 举报
回复
这样的话就导致了几个问题:
我第一次发送的包需要等待对方应答后才能接送第二个包。这样不阻塞的话就不知道第一个包送出去后对方的应答。例如FTP回话。
我发送一条登陆USER的命令出去。需等待应答才能送pass命令。在等待应答在送。。。。。。。
因为线路慢而导致包还没到第二个包就到了。这样回话就肯定错误。。。。
flyinair2000 2005-02-15
  • 打赏
  • 举报
回复
你调用asyncsocket send以后,根本就不要管了。它是肯定会send完的。当然,如果是一个大包,可能分成几次送。你处理的时候是需要判断一下的。

你可以到www.codeguru.com上找一个这样的例子,多的很。
my15y 2005-02-14
  • 打赏
  • 举报
回复
就算Thread线程来接收。也好像无法知道什么时候接收完数据。(除非例如ftp这样的接收完文件后就被断开。阻塞模式中。难道就真没有办法?

select 除非设置接收超时。否则也是一样。。。。
my15y 2005-02-14
  • 打赏
  • 举报
回复
怎么加分哦。。
my15y 2005-02-14
  • 打赏
  • 举报
回复
嗯。谢了。但是AsyncSocket好像有不少问题。这个到不是阻塞调用。
我只所以改用阻塞模式的socket是在用asyncsocket碰到些问题。因小弟我刚学不久所以不知道怎么解决:问题同样还是在传送数据中:

asyncsocket 在发送数据是因为我需要等待远程计算机应答。所以。在发送后函数立即返回。我也不知道是不是真的发送完了。我接收到的数据是不是完整有没有漏掉的。又或者一个字符串它分成多少个包发送过来的。处理起来实在不知道如何下手。。CSocket是阻塞调用。重asyncsocket类派生而来。倒是简单化了好多东西。特别是数据传送接收方面。。刚用这个类。不知道好不好用 ^_^
flyinair2000 2005-02-14
  • 打赏
  • 举报
回复
比如文件传输,你可以在文件头上附加一个表示文件长度的整数,然后根据读到的字符数可以判断是否结束了。
flyinair2000 2005-02-14
  • 打赏
  • 举报
回复
比如文件传输吧。你不加一个末尾信号,recv是不知道结束的。
这个和block没有关系--你不block也要一样判断吧?
CSocket好像是block的吧。(记不太清楚了,n年前用的了)我用的是asyncsocket。
my15y 2005-02-14
  • 打赏
  • 举报
回复
另外不知道大家用那种方式的多? 阻塞的或非阻塞的socket?
对于windows程序 是使用csocket的多还是使用asyncsocket的多?or winsock?
my15y 2005-02-14
  • 打赏
  • 举报
回复
明白你的意思。我其实担心的是数据是否全部接收。例如文件传输。。或FTP
接收到的数据主要就是写到文件而已。
flyinair2000 2005-02-14
  • 打赏
  • 举报
回复
我说的用Thread处理不是为了判断是否收完的,是为了不影响你主程序的处理。

你不对收到的数据进行判断,怎么可能呢?什么叫“接受完”啊?没有一个定位标志,怎么叫作“完”?
比如我send一下,小sleep一下再send,没有标志你能知道我什么时候是结束?
这不是技术问题,而是一个逻辑问题啊!
flyinair2000 2005-02-13
  • 打赏
  • 举报
回复
为什么一定要用block呢?
用select不行?

即使要用block模式,你也要在recv是新开一个thread 或者fork 一个process才行吧。
我的看法:你是无法知道数据是否传送完毕的。(如果你一定要这样实现的话,或者你可以在发送的数据后加标志位试试,这样recv后检查收到的buffer判断一下。)
my15y 2005-02-13
  • 打赏
  • 举报
回复
问题是不返回(阻塞中)
例如一个2048字节的数据传送
例如调用3此recv可接收完。问题第三次调用了recv后。返回的cc还是有字节。当第四次调用则recv阻塞..直到有数据可接收。。。
那么我如何知道它第三次调用recv后数据就传送完毕了呢?不用等待第4次调用的返回?
healer_kx 2005-02-13
  • 打赏
  • 举报
回复
函数返回的就是接受数据结束了。
一、WinSock简介 Socket(套接字)最初是由加利福尼亚大学Berkeley(伯克利)分校为UNIX操作系统开发的网络通信接口,随着UNIX的广泛使用,Socket成为当前最流行的网络通信应用程序接口之一。20世纪90年代初,由Sun Microsystems,JSB,FTP software,Microdyne和Microsoft等几家公司共同定制了一套标准,即Windows Socket规范,简称WinSock。 VB编写网络程序主要有两种方式:1.winsock控件 2.winsockAPI 二、WinSock控件的使用 1.WinSock控件的主要属性 LocalHostName属性 本地机器名 LocalIP属性 本地机器IP地址 LocalPort属性 本地机器通信程序的端口(0<端口<65536) RemoteHost属性 远程机器名 RemotePort属性 远程机器的通信程序端口 Protocol属性 通过Protocol属性可以设置WinSock控件连接远程计算机使用的协议。可选的协议是TCP和UDP对应的VB的常量分别是sckTCPProtocol和sckUDPProtocol,Winsock控件默认协议是TCP。注意:虽然可以在运行时设置协议,但必须在连接未建立或断开连接后。 SocketHandle属性 返回当前socket连接的句柄,这是只读属性。 RemoteHostIP属性 属性返回远程计算机的IP地址。在客户端,当使用了控件的Connect方法后,远程计算机的IP地址就赋给了RemoteHostIP属性,而在服务器端,当ConnectRequest事件后,远程计算机(客户端)的IP地址就赋给了这个属性。如果使用的是UDP协议那么当DataArrival事件后,发送UDP报文的计算机的IP才赋给了这个属性。 ByteReceived属性 返回当前接收缓冲区中的字节数 State属性 返回WinSock控件当前的状态 常数 值 描述 sckClosed 0 缺省值,关闭。 SckOpen 1 打开。 SckListening 2 侦听 sckConnectionPending 3 连接挂起 sckResolvingHost 4 识别主机。 sckHostResolved 5 已识别主机 sckConnecting 6 正在连接。 sckConnected 7 已连接。 sckClosing 8 同级人员正在关闭连接。 sckError 9   错误 2.WinSock主要方法 Listen方法 方法用于服务器程序,等待客户访问。格式:Winsock对象.listen Connect方法 用于向远程主机发出连接请求。格式:Winsock对象.connect [远程主机IP,远程端口] Accept方法 用于接受一个连接请求。格式:Winsock对象.accept Request ID Senddata方法 用于发送数据。格式:Winsock对象.senddata 数据 Getdata方法 用来取得接收到的数据。格式:Winsock对象.getdata 变量 [,数据类型 [,最大长度]] Close方法 关闭当前连接。格式:Winsock对象.close Bind方法 用Bind方法可以把一个端口号固定为本控件使用,使得别的应用程序不能再使用这个端口。 Listen方法Listen方法只在使用TCP协议时有用。它将应用程序置于监听检测状态。 Connect方法 当本地计算机希望和远程计算机建立连接时,就可以调用Connect方法。Connect方法调用的规范为:Connect RemoteHost,RemotePort Accept方法 当服务器接收到客户端的连接请求后,服务器有权决定是否接受客户端的请求。 SendData方法当连接建立后,要发送数据就可以调用SendData方法,该方法只有一个参数,就是要发送的数据。 GetData方法 当本地计算机接收到远程计算机的数据时,数据存放在缓冲区中,要从缓冲区中取出数据,可以使用GetData方法。GetData方法调用规范如下:GetData

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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