linux非阻塞connect

在linux的网络编程中经常会使用非阻塞模式的socket。在阻塞模式中,对于调用connect时是阻塞的,只有当socket连接建立起来或者连接出错是connect才返回。然而在阻塞模式中connect会立即返回,至于返回后的socket句柄是否是已经建立好可用的,它是不管的。这个就需要程序员自己写代码来判断,尤其是在做多个并发连接的筛选是尤为重要。然而一般的做法是用接口函数getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);的optval的值来判断,若optval为0则认为socket连接已经建立。

然而我最近写的代码却否定了这一种用法代码如下:

#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <cstdlib>

#include <openssl/ssl.h>
#include <openssl/err.h>

#define OUT(str) do{cout<<str<<endl;}while(0)
#define TEST do{printf("line:%d\n",__LINE__);}while(0)

using namespace std;


static int CreateScok(const char * ip){

	struct sockaddr_in serv_addr;
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_port=htons(443);
	serv_addr.sin_addr.s_addr=inet_addr(ip);
	bzero(&(serv_addr.sin_zero),8);
	

	SSL_CTX *ctx;
	SSL *ssl;

	SSL_library_init();
	OpenSSL_add_all_algorithms();
	SSL_load_error_strings();
	ctx= SSL_CTX_new(SSLv23_client_method());
	if(ctx == NULL) {
		return -1;
	}

	
	int sockfd;
	if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){

		OUT("socket create error");
		
		return -1;
	}

	
	int flags=fcntl(sockfd,F_GETFL,0);
	fcntl(sockfd,F_SETFL,flags|O_NONBLOCK);

	int n=connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr));	

	sleep(2);

	if(n<0){
		
		if(errno !=EINPROGRESS){
			perror(strerror(errno));
			return -1;
		}else{
			OUT(ip);
			OUT("EINPROGRESS");
		}
	}else{
		OUT(ip);
	}

	ssl= SSL_new(ctx);
	if(SSL_set_fd(ssl, sockfd) == 0){
		return -1;
	}
	SSL_set_connect_state(ssl);

	
	if(n==0){

		OUT("connect sucess immediately");
		return sockfd;
	}
	
	return sockfd;

}


int main(){

	ifstream ipin("./iplist.txt");
		
	string line;
	
	while(getline(ipin,line)){
	
		int sock=CreateScok(line.c_str());

		if(sock==-1){

			OUT("connect error");

			return 0;
		}else{

			int ret,error=1;

			socklen_t len;
				
			len=sizeof(error);

			OUT("fd:");
		
			OUT(sock);

			sleep(3);

			ret=getsockopt(sock,SOL_SOCKET,SO_ERROR,&error,&len);
		
			if(error == 0){

				OUT("SUCESS");
			}

			OUT("\n\n");
		}

		//close(sock);
	}
		
	return 0;
}
当我获得正在运行的该程序的进程号并查看它的所有的fd状态时发现在程序中通过getsockopt检验的fd的状态依然是SYN_SENT。有些不太明白,希望各位大牛不吝赐教。
联系方式:zhaosendong@hotmail.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值