socket发送数据遇到的问题?

fhw217 2015-07-06 12:43:54
socket是阻塞模式,超时设为5秒,socket缓冲区大小为默认,连续调用两次send:

send(...); // 一次性发送1MB数据
send(...); //发送5个字节

我用的是ADSL宽带,发送速度只有70KB/S左右,
但第一个send立即成功返回了,难道是把1MB数据都放在socket缓冲区中了?十几秒后接收方收到了这1MB数据。
第二个send返回超时错误(错误号: 0x0000274c),好像是在等待第一个send中的数据完成发送,请问这是什么原因,如何解决?
...全文
318 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
yaozhiyong110 2015-07-06
  • 打赏
  • 举报
回复
struct timeval* timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态: 第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止; 第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值; 第三,timeout的值大于0,这就是等待的超时时间,即 select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。 推荐你设置时间1秒左右 返回后如果返回值是0 说明没事件产生这时你可以sleep(20) 这种方式不会浪费cpu...
yaozhiyong110 2015-07-06
  • 打赏
  • 举报
回复
引用 5 楼 fhw_bin_dl 的回复:
[quote=引用 3 楼 yaozhiyong110 的回复:] 就是你发送太快了 等对方接收了 你的send就会成功了 所以为了效率 你至少用下select、event等等这些简单的模式...
在第2个send之前,用select无限期地判断socket是否可写,这种方法会不会造成程序无响应(程序一直处于假死状态)? [/quote] int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout); /*参数列表 int maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在Windows中这个参数的值无所谓,可以设置不正确。    fd_set *readfds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的,即我们关心是否可以从这些文件中读取数据了,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。    fd_set *writefds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的,即我们关心是否可以向这些文件中写入数据了,如果这个集合中有一个文件可写,select就会返回一个大于0的值,表示有文件可写,如果没有可写的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的写变化。    fd_set *errorfds同上面两个参数的意图,用来监视文件错误异常。    struct timeval* timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态: 第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止; 第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值; 第三,timeout的值大于0,这就是等待的超时时间,即 select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。 */ /* 返回值: 负值:select错误 正值:某些文件可读写或出错 0:等待超时,没有可读写或错误的文件 */ 具体你可以自己百度的...
fhw217 2015-07-06
  • 打赏
  • 举报
回复
引用 1 楼 pcradio 的回复:
你在第二个send后加int errno = GetLastError();把errno这个错误吗输入vc6 的工具ErrorLookup里去查看错误描述,你就知道为什么失败了
出错的原因是第2个send超时了。
fhw217 2015-07-06
  • 打赏
  • 举报
回复
引用 3 楼 yaozhiyong110 的回复:
就是你发送太快了 等对方接收了 你的send就会成功了 所以为了效率 你至少用下select、event等等这些简单的模式...
在第2个send之前,用select无限期地判断socket是否可写,这种方法会不会造成程序无响应(程序一直处于假死状态)?
赵4老师 2015-07-06
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
yaozhiyong110 2015-07-06
  • 打赏
  • 举报
回复
就是你发送太快了 等对方接收了 你的send就会成功了 所以为了效率 你至少用下select、event等等这些简单的模式...
shenyi0106 2015-07-06
  • 打赏
  • 举报
回复
send 返回并不表示数据发送成功,它只表示数据被拷贝到了发送缓冲区,下面将有协议栈来完成物理传输过程。 当协议栈在发送数据时,发送缓冲区是锁定的,这时在往里面拷贝数据是不成功的;也就是说,在发送数据时,在send是会失败的。所以每次send都需要检查返回值。
阿源是少年 2015-07-06
  • 打赏
  • 举报
回复
你在第二个send后加int errno = GetLastError();把errno这个错误吗输入vc6 的工具ErrorLookup里去查看错误描述,你就知道为什么失败了

18,356

社区成员

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

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