socket堵塞的解决方法
来源:互联网 发布:mama投票软件 编辑:程序博客网 时间:2024/06/02 17:22
进行网络开发会出现堵塞的情况,一般来说,会有三种解决办法:
- 在头部约定好数据的长度。当读取到的长度等于这个长度时就不再继续调用recv方法
- 约定结束标志,当读到该结束标志时退出不再recv
- 设置超时,会在设置的超时时间到达后退出而不再阻塞
第一种方法简单实用,但是如果返回头信息中是transfer-encoding:chunked,即分块传输的情况无法使用;
第二种方法碰到比较复杂的返回不好处理;
第三种可以,但是对网络的要求比较高。
对于分块传输的情况则不能通过Content-Length:xx来获取报文长度,我是通过设置超时来解决的,代码如下:
while(1) { FD_ZERO(&rfds);//清空描述符集合 FD_SET(0, &rfds);//将标准输入(stdin)添加到集合中 FD_SET(socket_fd, &rfds);//将我们的套接字描述符添加到集合中 /*设置超时时间*/ timeout.tv_sec = 1; timeout.tv_usec = 0; /*监听套接字是否超时*/ if(select(socket_fd+1, &rfds, NULL, NULL, &timeout) <= 0)break; memset(lpbuf2,0,BUFFER_SIZE); bytes_received = recv(socket_fd, lpbuf2, BUFFER_SIZE, 0); /*获取网络字节*/ if(bytes_received > 0) { strncpy(res,lpbuf2,bytes_received); sprintf(response + strlen(response),"%s",res); } }
获取的字符串是如下的形式:
head: headdata\r\n ………头信息
\r\n
len1\r\n ….分块传输的第一块的长度
body1\r\n …..分块传输的第一块
len2\r\n …..分块传输的第二块的长度
body2\r\n …..分块传输的第二块
…\r\n ……………分块传输的第n块的长度和第n块
0\r\n ………..结束符
\r\n
可以发现,约定了结束标志\r\n0\r\n,可以使用第三种方法,感兴趣的可以自己试试,然后是对获取的如上形式的字符串解析,获取body1body2这样形式的真正的内容。
代码如下:
char *http_parse_result(const char*lpbuf){ char *ptmp = NULL; static char response[16384] = ""; int len; char chunkedbody[16384] = ""; ptmp = (char*)strstr(lpbuf,"HTTP/1.1"); if(!ptmp){ printf("http/1.1 not faind\n"); return NULL; } if(atoi(ptmp + 9)!=200){ printf("result:\n%s\n",lpbuf); return NULL; } ptmp = (char*)strstr(lpbuf,"\r\n\r\n");//\r\n\r\n1fbd\r\nbody\r\n1223\r\nbody\r\n0\r\n\r\n if(!ptmp){ printf("ptmp is NULL\n"); return NULL; } ptmp = ptmp + 4;//1fbd\r\nbody\r\n1223\r\nbody\r\n0\r\n\r\n printf("ptmp=%s\n",ptmp); while(*ptmp != '\0') { len = strtol(ptmp,NULL,16); if(len == 0) { response[strlen(response)] = '\0'; break; } printf("len=%d\n",len); ptmp = (char*)strstr(ptmp,"\r\n");//\r\nbody1\r\n1223\r\nbody2\r\n0\r\n\r\n strncpy(chunkedbody,ptmp + 2,len); printf("chunkedbody=%s\n",chunkedbody); sprintf(response+strlen(response),"%s",chunkedbody); memset(chunkedbody,0,16384); ptmp = ptmp + len + 4;//1223\r\nbody2\r\n0\r\n\r\n } return response;}
就这样,有一点需要注意的是获取的网络字节是unicode形式的,需要先编码再解析。
阅读全文
1 0
- socket堵塞的解决方法
- 关于socket的接收堵塞问题
- 关于socket的接收堵塞问题
- 关于socket的接收堵塞问题
- socket 堵塞非堵塞那些事
- swftools转换文件时线程堵塞问题的解决方法
- swftools转换文件时线程堵塞问题的解决方法
- java执行cmd命令出现堵塞现象的解决方法
- SAP IDOC的堵塞
- 查看堵塞的SQL
- VC中将SOCKET类的connect函数设置为非堵塞
- VC中将SOCKET类的connect函数设置为非堵塞
- sql的select出现堵塞导致程序卡死的解决方法(在事务中查询)
- WSAAsyncSelect模型Socket消息堵塞问题
- socket客户端接收信息被堵塞
- 马桶堵塞所想到的
- SQLServer的一次堵塞分析
- 无堵塞的脚本加载
- 理解Hinton的Capsule Networks1
- Iterable和Iterator的辨析
- 如何根据指定字符替换换行符
- Objective-c 冒泡排序和选择排序
- mysql增量备份还原详解
- socket堵塞的解决方法
- Nginx的启动、关闭和重启
- Hibernate的学习之路十二(session的快照机制)
- 简单四步完成Oracle创建表空间
- Android系统字体大小如何影响app的字体大小?
- 什么是索引?索引有哪几种?什么时候使用索引比较好?
- 基于Spring的QQ第三方登录实现
- Spring Security3.1登陆验证(转)
- Cron表达式