- 浏览: 266334 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
AndMacLinuXp:
试了下,不错!
printk内核调试 -
klose:
我引用你的文章,并做了简单的分析:这里贴出url:http:/ ...
linux系统调用fork, vfork, clone -
klose:
你上面提到的问题:free的问题。首先你可能疏忽了,stack ...
linux系统调用fork, vfork, clone -
qwe_rt:
HI ,非常nice的文章,在阅读过程中,我发现我的ubunt ...
linux手动添加开机启动的服务 -
suifeng:
谢谢分享, 受用中.
shell编程分支,循环
connect非阻塞套接口时候,一般使用在以下几种情况:
1.三路握手需要时间,这个要视具体的网络情况而定。当然也有可能失败。在三路握手的时候我们并不需要在原地等待三路握手的完成,可以用这些时间来 完成其它事情,然后当这些事情完成后,再去检测连接是否建立(也就是三路握手是否完成)。
2.可以用这种技术来同时建立多个连接。(WEB浏览器中很常用)。
3.connect超时需要很长时间才会通知,如果我们认为超过0.1秒以后就算超时(不管它是不是真的超时),这是就可以使用非阻塞式I/O结合 select来完成。
当采用非阻塞式I/O来使用connect时候,要判断一个连接是否建立则比较复杂,需要按照以下几个步骤来完成
1.即使是使用非阻塞式的connect操作,connect依然可能正确返回,也就是说非阻塞的connect 也有可能三路连接完成后返回,这种情况一般发生在服务器和主机在同一个机器上,所以第一步要判断connect是否正确返回,如果正确返回则请做正确返回 的处理,否则进入步骤2
2.设置fd_set,(如果没看明白,请先看select函数介绍),让select函数同时监听套接字的读写2个属性,如果既可读也可写则进入 步骤3,如果可写但不可读进入步骤4.
3.如果到达这步,我们需要调用getsockopt进一步判断。这里涉及到一个移植问题,getsockopt如果发生错误, 源自Berkeley的实现会返回0,如果是solaris,则会返回-1。建议是2个都处理(如果看不明白请先看getsockopt函数,套接口选 项)。根据getsockopt通过参数返回的erron的值,如果值为0则表示链接建立完成,如果不为0, 则说明链接建立没有完成。
4.如果能到达这里,则说明连接建立完成。
最后,即使最后你得出链接没有建立完成,也只是说:可能三路握手的过程还是没有完成。
代码:
服务器
#include "/programe/net/head.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define MAXSIZE 100
//如果这样写,最后返回的套接口应该是会进入步骤3,也就是套接口既可读也可写,如果想进入步骤4,就不要想套接口中写入数据
int main(int argc, char ** argu) {
int listenfd, connfd;
struct sockaddr_in servaddr;
char buf[MAXSIZE + 1];
char buf2[] = "hello world\n";
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(atoi(argu[1]));
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 10);
for(;;) {
connfd = accept(listenfd, (struct sockaddr *)NULL, NULL);
write(connfd, buf2, sizeof(buf2));
close(connfd);
}
}
客户端
#include "/programe/net/head.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "fcntl.h"
#include "sys/select.h"
#define MAXSIZE 100
int main(int argc, char ** argv) {
int sockfd, n;
int my;
char send_buf[MAXSIZE + 1];
char recv_buf[MAXSIZE + 1];
struct sockaddr_in servaddr;
int error = 0;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("create socket error\n");
exit(1);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[1]));
if(inet_pton(AF_INET, "192.168.1.235" , &servaddr.sin_addr) < 0) {
printf("inet_pton error\n");
exit(1);
}
int val = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, val | O_NONBLOCK); //设置套接口非阻塞
int connect_flag = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in));
sleep(2); //connect会立即返回,不同于之前的要阻塞到链接完成才会返回,这里可以做你想在等待连接完成的时间想做的事情,我这里只是让进程睡眠了一段时间
if(connect_flag >= 0) {
printf("connect success\n"); //即使是非阻塞套接口,connect还是有可能正确返回的,这种情况要处理
goto done; //不建议使用goto
}
fd_set rest, west;
FD_ZERO(&rest);
FD_ZERO(&west);
FD_SET(sockfd, &rest);
FD_SET(sockfd, &west);
int maxpd = sockfd + 1;
int flag = select(maxpd, &rest, &west, NULL, NULL);//监听套接的可读和可写条件
if(flag < 0) {
printf("select error\n");//慢系统调用可能会错误返回,这个以前提过
exit(1);
}
if(FD_ISSET(sockfd, &rest) && FD_ISSET(sockfd, &west)) {//如果套接口及可写也可读,需要进一步判断
socklen_t len = sizeof(error);
if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
exit(1);//获取SO_ERROR属性选项,当然getsockopt也有可能错误返回
printf("error = %d\n", error);
if(error != 0) {//如果error不为0, 则表示链接到此没有建立完成
printf("connect failed\n");
exit(1);
}
//如果error为0,则说明链接建立完成
}
if(FD_ISSET(sockfd, &west) && !FD_ISSET(sockfd, &rest)) { //如果套接口可写不可读,则链接完成
printf("connect success\n");
}
done:
int recv_buf_len = read(sockfd, recv_buf, MAXSIZE);
recv_buf[recv_buf_len] = '\0';
printf("get message:%s", recv_buf);
close(sockfd);
exit(0);
}
发表评论
-
hdfs集群搭建
2014-05-11 17:19 998网上很多hadoop集群搭建的文章,我这里只写下hdfs,不 ... -
网站性能优化
2013-10-25 10:43 0好久没写了,最近一直在做些互联网的一些东西。下面介绍些性能优 ... -
html5学习网站
2011-07-29 14:55 902htm5:http://www.w3school.com.cn ... -
HTTP下载
2011-02-09 15:24 1082HTTP下载的关键是修改Content-Type。 C ... -
28.sniffer程序2
2010-07-01 17:51 1768对前面27中sniffer中的一 ... -
27. sniffer程序
2010-06-30 11:51 5909网络抓包,必需从数据链路层开始抓取,至于原因之前在原始套接口中 ... -
java 和 linux c udp通信的样例
2010-05-28 11:58 2463一个简单的例子 java段(客户端) package ... -
26.原始套接字
2010-05-12 16:45 1759一个小程序: //发送方 #include <sys ... -
25.cookies和session
2010-05-10 15:21 893原文出自:http://blog.csdn ... -
24.SOCKET模拟HTTP请求
2010-05-07 14:11 5318HTTP请求头部样例: GET http://www.bai ... -
23.广播
2010-04-29 16:34 940如果想发送广播到目前为止只能使用AF_INET, SOCK_D ... -
21.非阻塞I/O
2010-04-27 16:54 2071设置一个I/O成为非阻塞很简单,只需要: int val = ... -
20.辅助数据 和 传输描述字
2010-04-26 15:53 2063打开一个文件或者一个 ... -
19.unix域协议与TCP UDP不同之处
2010-04-22 13:46 2613之前说过一些区别,但基本对我们编程来说没有太多影响,但以下几个 ... -
18.unix域协议
2010-04-21 16:47 2621UNIX域协议并不是一个真正的协议族,它是用在同一台主机上进行 ... -
17.I/O函数recvmsg与sendmsg
2010-04-20 15:58 12421想对于之前的几个IO函 ... -
16.I/O函数
2010-04-20 13:51 1240最早使用的read与write函 ... -
15.服务器守护进程
2010-04-16 17:44 1394前面提到过的服务器都占有控制终端。而有些进程并不需要控制终端。 ... -
14.udp与connect
2010-04-13 16:41 3210UDP在调用sendto发送数据 ... -
13.UDP编程
2010-04-09 17:16 2255虽然UDP不保证传输的可 ...
相关推荐
linux客户端Socket非阻塞connect编程[归纳].pdf
linux客户端Socket非阻塞connect编程收集.pdf
网络实现非阻塞connect,select带超时
1. 编程理解(36) 1. 经典资料(15) 1. 开源项目(16) 9.SaaS-云存储,云服务(38) 9.SaaS-云计算-学习(38)
使用OTP原理构建一个非阻塞的TCP服务器
2.将该socket设置为非阻塞模式 3.调用connect() 4.使用select()检查该socket描述符是否可写(注意,是可写) 5.根据select()返回的结果判断connect()结果 6.将socket设置为阻塞模式(如果你的程序不需要用阻塞...
支持跨平台的非阻塞socket连接,no-block socket connect
异步消息通知 消息队列 发送队列 接口实现
第三章 进程控制 ..........................................................................................................22 3.1 进程的建立与运行 ........................................................
22 2 . 2 . 5多文件编译............ ........................................ 23 2.2.6 预处理........................................................ 24 2 . 2 . 7编译成汇编语言............................
首先采用非阻塞的connect,会立即返回,如果返回EINPROGRESS,表明正在连接属于正常,在此期间使用getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)获取socket的错误,无论对于正在连接还是连接完成都返回0,直到出现...
ts-postgres 用TypeScript编写的Node.js的非阻塞PostgreSQL客户端。安装要安装此库的最新版本: $ npm install ts-postgres@latest特征快速地! 支持二进制和文本值格式结果数据当前仅以二进制格式发送可以一次发送...
第三章 进程控制..........................................................................................................22 3.1 进程的建立与运行...........................................................
第三章 进程控制 ..........................................................................................................22 3.1 进程的建立与运行 .........................................................
socket客户端封装类,实现connect,read,write的非阻塞操作.
ngx_lua 的非阻塞 Lua FastDFS 驱动程序库 local tracker = require('resty.fastdfs.tracker') local storage = require('resty.fastdfs.storage') local tk = tracker:new() tk:set_timeout(3000) local ok, err =...
oauth.apisample.javaspringboot概述使用OAuth和Open Id... AWS Cognito用作默认授权服务器用于实现OAuth自定义过滤器用于通过简单的代码实现非阻塞API 可以将API日志汇总到以支持SSL证书certs文件夹中的证书源自存储库