c++ socket 阻塞recv()接收360浏览器http请求时不返回或返回很慢

落雁西南 2019-01-12 11:22:42

if( (connfd = accept(m_listenfd, (struct sockaddr*)NULL, NULL)) == -1){
printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
return -1;
}
struct timeval recv_time,start_time,send_time,end_time;
memset(recv_buf,0,MAX_HTTP_LEN);
gettimeofday(&recv_time,NULL);
printf("recv_time :%ld\n",recv_time.tv_sec*1000000+recv_time.tv_usec);
n = recv(connfd,recv_buf,MAX_HTTP_LEN,0);
gettimeofday(&start_time,NULL);
printf("start_time:%ld\n",start_time.tv_sec*1000000+start_time.tv_usec);


用来模拟接收http请求,同一个http的get请求用Windows或Linux下Firefox,chrome,IE发起时recv用时只有100微秒左右,但是如果在Windows下的用360浏览器的话,阻塞在recv()这里了,用抓包工具看了下http请求是到了的。
recv()没有返回的原因是什么?
...全文
437 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiyefangzhou24 2019-01-18
  • 打赏
  • 举报
回复
分析一下不同浏览器请求包不同点在哪里
bravery36 2019-01-18
  • 打赏
  • 举报
回复
记错了, 是MTU, 不是pdu....
bravery36 2019-01-18
  • 打赏
  • 举报
回复
同步recv返回有几种可能:
1)接收到指定的长度.
2)接收到一个pdu.可能是1500, 8000等等长度.
3)连接关闭.

MAX_HTTP_LEN不满足就不会返回, 长度不足不会返回.
Simple-Soft 2019-01-17
  • 打赏
  • 举报
回复
recv没有返回的原因可能是360浏览器没有返回或者返回的数据太少,把MAX_HTTP_LEN改小试试
网络编程,当然要用到Windows Socket(套接字)技术。Socket相关的操作由一系列API函数来完成,比如socket、bind、listen、connect、accept、send、sendto、recvrecvfrom等。调用这些API函数有一定的先后次序,有些函数的参数还比较复杂,对于开发者来说,不是很好用。于是,微软的MFC提供了两个类:CAsyncSocket和CSocket,极大地方便了Socket功能的使用。   CAsyncSocket类在较低层次上封装了Windows Socket API,并且通过内建一个(隐藏的)窗口,实现了适合Windows应用的异步机制(Windows Socket API默认情况下工作在阻塞模式,不方便直接在消息驱动的Windows程序上使用)。CSocket类从CAsyncSocket类派生,进一步简化了Socket功能的应用。不过很遗憾,正因为这两个类都内建了一个窗口,它们并不是线程安全的(thread-safe);如果要在多线程环境下应用Socket功能,建议自行封装Socket API函数。 基于TCP的socket编程的服务器端程序流程如下: 1、创建套接字 2、将套接字绑定到一个本地地址和端口号上(bind) 3、将套接字设为监听模式,准备接受客户请求(listen) 4、等待客户请求,请求到来接受请求,建立链接,并返回 一个新的基于此次通信的套接字(accept) 5、用返回的套接字和客户端进行通信(send、recv) 6、返回,等待另一客户请求 7、关闭套接字 基于TCP的socket编程的客户端程序流程如下: 1、创建套接字 2、向服务器端发送请求(connect) 3、和服务器端进行通信(send、recv) 4、关闭套接字 基于UDP的socket编程的服务器端程序流程如下: 1、创建套接字 2、将套接字绑定到本地地址和端口号上(bind) 3、等待接收数据(recvfrom) 4、关闭套接字 基于UDP的socket编程的客户端程序流程如下: 1、创建套接字 2、和服务器端进行通信(sendto) 3、关闭套接字 异步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而同步指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式。   阻塞套接字是指执行此套接字的网络调用,直到成功才返回,否则一直阻塞在此网络调用上,比如调用recv()函数读取网络缓冲区中的数据,如果没有数据到达,将一直挂在recv()这个函数调用上,直到读到一些数据,此函数调用才返回;而非阻塞套接字是指执行此套接字的网络调用,不管是否执行成功,都立即返回。比如调用recv()函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。在实际Windows网络通信软件开发中,异步非阻塞套接字是用的最多的。平常所说的C/S(客户端/服务器)结构的软件就是异步非阻塞模式的。   对于这些概念,初学者的理解也许只能似是而非,我将用一个最简单的例子说明异步非阻塞Socket的基本原理和工作机制。目的是让初学者不仅对Socket异步非阻塞的概念有个非常透彻的理解,而且也给他们提供一个用Socket开发网络通信应用程序的快速入门方法。操作系统是Windows 98(或NT4.0),开发工具是Visual C++6.0。   MFC提供了一个异步类CAsyncSocket,它封装了异步、非阻塞Socket的基本功能,用它做常用的网络通信软件很方便。但它屏蔽了Socket的异步、非阻塞等概念,开发人员无需了解异步、非阻塞Socket的原理和工作机制。因此,建议初学者学习编网络通信程序,暂且不要用MFC提供的类,而先用Winsock2 API,这样有助于对异步、非阻塞Socket编程机制的理解。

65,209

社区成员

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

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