#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;
}
socket阻塞详解
最新推荐文章于 2023-04-01 21:28:28 发布