socket阻塞详解

36 篇文章 0 订阅
4 篇文章 0 订阅
#include <stdio.h> 
#include <poll.h> 
#include <unistd.h>  
#include <stdlib.h>  
#include <string.h>  
#include <errno.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
#include <netdb.h> 
#include <sys/time.h> 

//设置socket
int AllocSocket()
{
	int fd = socket(AF_INET, SOCK_STREAM, 0);
	return fd;
}
//得到IP地址方式通过getaddrinfo
int getIpAddrByHostName ( const char * hostname, char * ip, int len, int family )
{

    int result = 0;

	//if any parameter is error ,return false
    if ( 0 == strlen(hostname) || len <=0 || (family != AF_INET && family != AF_INET6 ))
    {
        return result;
    }
    
    memset( ip, 0, len );

    //initialize the address information
    struct addrinfo hints, *res, *res0;
    int ret;

    memset(&hints, 0, sizeof(hints));
    
    hints.ai_family = family;
    hints.ai_socktype = SOCK_STREAM;
    ret = getaddrinfo( hostname, "", &hints, &res0);
	//if get address information unsuccessfully, return false.
    if (ret != 0 ) 
    {    
        return result;
    }
    //get the IP adress from all adress information
    for ( res = res0; res; res = res->ai_next) 
    {
        char buf [INET6_ADDRSTRLEN];
        memset (buf, 0, sizeof(buf)); 
        
        if ( res->ai_family == AF_INET )
        {
            struct sockaddr_in* pa = (struct sockaddr_in*)res->ai_addr;
            if ( inet_ntop(res->ai_family, &(pa->sin_addr), buf, sizeof(buf)) == 0 )
            {
                continue;
            }
    
        }
        else
        {
            struct sockaddr_in6 * pa = (struct sockaddr_in6*)res->ai_addr;
            if ( inet_ntop(res->ai_family, &(pa->sin6_addr), buf, sizeof(buf)) == 0 )
            {   
                continue;
            }   
        }

        //if the buffer of ip isn't long enough, return false.
        //strlen(buf) can't equals len, because the last byte of ip must be '\0'
        if ( strlen(buf) < len )
        {
		   printf("ip is : %s\n",buf);
            snprintf( ip, len, "%s", buf );
            //snstrcpy( ip, buf, strlen(buf) );
            result = 1;
        }
        else
        {
            result = 0;
        }       
        break;
    }
    //release the adress information
    if ( res0 != 0 )
    {
        freeaddrinfo(res0);
        res0 = 0;
    }
    return result;
    
}

int getIpAddrByHostName2(const char* hostname, char* ip, int len)
{
	int x, x2;  
    struct hostent *hp;  
   
 /*  
  * Look up the hostname:  
  */  
       hp = gethostbyname(hostname);  
       if ( !hp )
	   { //Report lookup failure    
          fprintf(stderr,  
                  "%s: host '%s'\n",  
                  hstrerror(h_errno),  
                  hostname);  
       }  
  
 /*    
  * Report the findings:  
  */  
       printf("Host %s : \n" ,hostname);  
       printf(" Officially:\t%s\n", hp->h_name);  
       fputs(" Aliases:\t",stdout);  
       for ( x2=0; hp->h_aliases[x2]; ++x2 ) 
	   {  
          if ( x2 ) 
		  {  
             fputs(", ",stdout);  
          }  
		  fputs(hp->h_aliases[x2],stdout);  
       }  
       fputc('\n',stdout);  
       printf(" Type:\t\t%s\n",  
              hp->h_addrtype == AF_INET  
              ? "AF_INET" : "AF_INET6");  
       if ( hp->h_addrtype == AF_INET ) 
	   {  
          for ( x2=0; hp->h_addr_list[x2]; ++x2 ) 
		  {  
             printf(" Address:\t%s\n",  
                    inet_ntoa( *(struct in_addr *)  
                     hp->h_addr_list[x2]));  
          }  
       }  
       char ipAddr[64];  
        inet_ntop(AF_INET,hp->h_addr,ipAddr,sizeof(ipAddr));      
        printf("ip is : %s\n",ipAddr);
		snprintf( ip, len, "%s", ipAddr );
		return 0;
}

int SetSocket(int fd, char* ip,int port)
{
	  int type;  
	  struct sockaddr_in sin;  
	  struct sockaddr_in6 sin6;  
	  memset(&sin, 0, sizeof(sin));  
	  memset(&sin6, 0, sizeof(sin6));
	 if ( inet_pton( AF_INET, ip, &sin.sin_addr ) == 1 )  
	 {  
		type = AF_INET;  
		sin.sin_family = AF_INET;  
		sin.sin_port = htons (port); 
		sin.sin_addr.s_addr= inet_addr(ip);
	 }  
	 else 
     {  
          if ( inet_pton(AF_INET6, ip, &sin6.sin6_addr ) == 1 )  
         {  
            type = AF_INET6;  
            sin6.sin6_family = AF_INET6;  
            sin6.sin6_port = htons (port); 
  	     //sin6.sin6_addr.s6_addr = inet6_addr(ip);
	     }
	}
	int on;
	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
	{
		printf("set socketopt error");
		return 1;
	}
	return 0;
 }
 
 /*通过poll处理超时*/
int ServerHanderBypoll(int fd, int _pipe[0])
{
	struct pollfd *pollclient = NULL;
	while(1)
	{
		pollclient = (struct pollfd*)malloc(sizeof(struct pollfd) *2);
		memset(pollclient, 0, sizeof(struct pollfd));
		
		pollclient[0].fd = fd;
		pollclient[0].events = POLLIN;

		pollclient[1].fd = _pipe[0];
		pollclient[1].events = POLLIN;
		
		int timeout = 200*1000;
		int rc = poll(pollclient, 2, timeout);
		if(rc < 0)
		{
			printf("error\n");
			free(pollclient);
		}
		else if(rc == 0)
		{
			free(pollclient);
			continue;
		}
		else
		{
			if(pollclient[1].revents &(POLLIN | POLLERR))
			{
				int len;
				char buf[64]={0};
				len = read(_pipe[0], buf, 64);
				if(len <= 0)
					break;
				printf("read from pipe. len =%d, buf=%s\n", len,buf);	
			}
			if(pollclient[0].revents &(POLLIN | POLLERR))
			{
				int n = 0;
				char buf[64]={0};
			 read_again:
				n = read(fd,buf,64);
				switch(n)
				{
				 /*close by peer*/
					case 0:
					 printf("close by peer\n");
					 break;
					case 1:
						if(errno == EINTR)
						{
							 printf("errno is EINTR\n");
							goto read_again;
						}
						else
						{
							return -2;
						}
					default:
						printf("read from socket. len =%d, buf=%s\n", n,buf);	
						break;
				}
			}
		}
	}
}
int ServerHanderByselect(int fd, int _pipe[0])
{
	struct timeval curtime;
	curtime.tv_sec =5;
	curtime.tv_usec =5000;

		fd_set rd_set;
		char buf[20];
		strcpy(buf,"select test");
		FD_ZERO(&rd_set);
		FD_SET(fd,&rd_set);
		FD_SET(_pipe[0],&rd_set);
		int max = fd > _pipe[0]? fd : _pipe[0];
		int ret = select(max+1,&rd_set,NULL,NULL,&curtime);
		 printf("ret = %d\n",ret);
		if(ret <0 )
		{
			printf("error");
		}
		else
		{
			printf("there is no read content");
		}
        if(FD_ISSET(_pipe[0],&rd_set))  
        {  
//              close(pipearr[1]);  
                char buf[20];  
                read(_pipe[0],buf,sizeof(buf));  
                printf("pipe[0] is ok\n" );  
                printf("read content is %s\n",buf );  
        }  
        else if(FD_ISSET(fd,&rd_set)) 
        {  
              	char buf[64]={0};
				int n = 0;	
				n = read(fd,buf,64);
				printf("read content is %s\n",buf );  
        } 
	    else
		{
			printf("error\n");
		}
	
}
 
int main(int argc, char** argv)
{
	int _pipe[2];
	pipe(_pipe);
	char* buf = "this is test poll with pipe";
	write(_pipe[1], buf, strlen(buf));

	int fd = AllocSocket();
	char listen_IP[64] = {0};
	//method 1
	if ( 0 == getIpAddrByHostName("localhost", listen_IP, 64, AF_INET) )
	{
		printf("Get Ip Address error\n");
	}
	struct sockaddr_in servaddr;
	memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr(listen_IP);
    servaddr.sin_port = htons(5566);
	//method 2
	//getIpAddrByHostName2("localhost", len, listen_IP);
	//设置socket选项
	if(SetSocket(fd,listen_IP,5566) != 0)
	{	
		printf("set socket error\n");
	}
	else
	{
		printf("set socket over\n");
	}
	  if(bind(fd, (struct sockaddr *)(&servaddr), sizeof(servaddr)) < 0)
    {
  
		printf("bind error");
    }

    if(listen(fd, 64) == -1)
    {
      printf("listen error");
    }
	
	//ServerHanderBypoll(fd, _pipe);
	ServerHanderByselect(fd, _pipe);
	
	return 0;
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值