用c/c++語言在IPv6下的socket通信編程

下面為Daytime這個服務的源代碼例子挫掏,同時兼容IPV6和IPV4的地址堡称,最后部分有更多說明乳乌。

單播模式下的Server方代碼:

"listen_server.h":

#ifndef listen__server__h__

#define listen__server__h__

/*

listen_server

creates a server server socket listening at a hostname:service

using the family and socket type specified in the function

arguments.

*/

int

listen_server(const char *hostname,

const char *service,

int?????????family,

int?????????socktype);

#endif

"listen_server.cpp":

#include

#include

#include

#include

#include "listen_server.h"

const int LISTEN_QUEUE=128;

int

listen_server(const char *hostname,

const char *service,

int?????????family,

int?????????socktype)

{

struct addrinfo hints, *res, *ressave;

int n, sockfd;

memset(&hints, 0, sizeof(struct addrinfo));

/*

AI_PASSIVE flag: the resulting address is used to bind

to a socket for accepting incoming connections.

So, when the hostname==NULL, getaddrinfo function will

return one entry per allowed protocol family containing

the unspecified address for that family.

*/

hints.ai_flags????= AI_PASSIVE;

hints.ai_family???= family;

hints.ai_socktype = socktype;

n = getaddrinfo(hostname, service, &hints, &res);

if (n <0) {

fprintf(stderr,

"getaddrinfo error:: [%s]\n",

gai_strerror(n));

return -1;

}

ressave=res;

/*

Try open socket with each address getaddrinfo returned,

until getting a valid listening socket.

*/

sockfd=-1;

while (res) {

sockfd = socket(res->ai_family,

res->ai_socktype,

res->ai_protocol);

if (!(sockfd < 0)) {

if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0)

break;

close(sockfd);

sockfd=-1;

}

res = res->ai_next;

}

if (sockfd < 0) {

freeaddrinfo(ressave);

fprintf(stderr,

"socket error:: could not open socket\n");

return -1;

}

listen(sockfd, LISTEN_QUEUE);

freeaddrinfo(ressave);

return sockfd;

}

TCP模式 "tcp_daytime_server.cpp":

#include

#include

#include

#include

#include

#include

#include

#include "listen_server.h"

const char *DAYTIME_PORT="13";

int

main(int argc, char *argv[])

{

int listenfd, connfd;

socklen_t addrlen;

char timeStr[256];

struct sockaddr_storage clientaddr;

time_t now;

char clienthost[NI_MAXHOST];

char clientservice[NI_MAXSERV];

/* local server socket listening at daytime port=13 */

listenfd = listen_server( NULL, DAYTIME_PORT,

AF_UNSPEC, SOCK_STREAM);

if (listenfd < 0) {

fprintf(stderr,

"listen_socket error:: could not create listening "

"socket\n");

return -1;

}

for ( ; ;) {

addrlen = sizeof(clientaddr);

/* accept daytime client connections */

connfd = accept(listenfd,

(struct sockaddr *)&clientaddr,

&addrlen);

if (connfd < 0)

continue;

memset(clienthost, 0, sizeof(clienthost));

memset(clientservice, 0, sizeof(clientservice));

getnameinfo((struct sockaddr *)&clientaddr, addrlen,

clienthost, sizeof(clienthost),

clientservice, sizeof(clientservice),

NI_NUMERICHOST);

printf("Received request from host=[%s] port=[%s]\n",

clienthost, clientservice);

/* process daytime request from a client */

memset(timeStr, 0, sizeof(timeStr));

time(&now);

sprintf(timeStr, "%s", ctime(&now));

write(connfd, timeStr, strlen(timeStr));

close(connfd);

}

return 0;

}

UDP模式 "udp_daytime_server.cpp":

#include

#include

#include

#include

#include

#include

#include "listen_server.h"

const char *DAYTIME_PORT="13";

int

main(int argc, char *argv[])

{

int listenfd, n;

socklen_t addrlen;

char *myhost;

char timeStr[256];

struct sockaddr_storage clientaddr;

time_t now;

char b[256];

char clienthost[NI_MAXHOST];

char clientservice[NI_MAXSERV];

myhost=NULL;

if (argc > 1)

myhost=argv[1];

listenfd= listen_server(myhost, DAYTIME_PORT, AF_UNSPEC, SOCK_DGRAM);

if (listenfd < 0) {

fprintf(stderr,

"listen_server error:: could not create listening "

"socket\n");

return -1;

}

addrlen = sizeof(clientaddr);

for ( ; ;) {

n = recvfrom(listenfd,

b,

sizeof(b),

0,

(struct sockaddr *)&clientaddr,

&addrlen);

if (n < 0)

continue;

memset(clienthost, 0, sizeof(clienthost));

memset(clientservice, 0, sizeof(clientservice));

getnameinfo((struct sockaddr *)&clientaddr, addrlen,

clienthost, sizeof(clienthost),

clientservice, sizeof(clientservice),

NI_NUMERICHOST);

printf("Received request from host=[%s] port=[%s]\n",

clienthost, clientservice);

memset(timeStr, 0, sizeof(timeStr));

time(&now);

sprintf(timeStr, "%s", ctime(&now));

n = sendto(listenfd, timeStr, sizeof(timeStr), 0,

(struct sockaddr *)&clientaddr,

addrlen);

}

return 0;

}

單播模式下的Client方代碼:

"connect_client.h":

#ifndef connect__client__h__

#define connect__client__h__

int

connect_client (const char *hostname,

const char *service,

int?????????family,

int?????????socktype);

#endif

"connect_client.cpp":

#include

#include

#include

#include

#include "connect_client.h"

int

connect_client (const char *hostname,

const char *service,

int?????????family,

int?????????socktype)

{

struct addrinfo hints, *res, *ressave;

int n, sockfd;

memset(&hints, 0, sizeof(struct addrinfo));

hints.ai_family = family;

hints.ai_socktype = socktype;

n = getaddrinfo(hostname, service, &hints, &res);

if (n <0) {

fprintf(stderr,

"getaddrinfo error:: [%s]\n",

gai_strerror(n));

return -1;

}

ressave = res;

sockfd=-1;

while (res) {

sockfd = socket(res->ai_family,

res->ai_socktype,

res->ai_protocol);

if (!(sockfd < 0)) {

if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)

break;

close(sockfd);

sockfd=-1;

}

res=res->ai_next;

}

freeaddrinfo(ressave);

return sockfd;

}

TCP模式 "tcp_daytime_client.cpp":

#include

#include

#include

#include

#include

#include

#include "connect_client.h"

const char *DAYTIME_PORT="13";

int

main(int argc, char *argv[])

{

int connfd;

char *myhost;

char timeStr[256];

myhost = "localhost";

if (argc > 1)

myhost = argv[1];

connfd= connect_client(myhost, DAYTIME_PORT, AF_UNSPEC, SOCK_STREAM);

if (connfd < 0) {

fprintf(stderr,

"client error:: could not create connected socket "

"socket\n");

return -1;

}

memset(timeStr, 0, sizeof(timeStr));

while (read(connfd, timeStr, sizeof(timeStr)) > 0)

printf("%s", timeStr);

close(connfd);

return 0;

}

UDP模式 "udp_daytime_client.cpp":

#include

#include

#include

#include

#include

#include

#include "connect_client.h"

const char *DAYTIME_PORT="13";

int

main(int argc, char *argv[])

{

int connfd, n, m;

char *myhost;

char timeStr[256];

char letter;

myhost = "localhost";

if (argc > 1)

myhost=argv[1];

connfd = connect_client(myhost, DAYTIME_PORT, AF_UNSPEC, SOCK_DGRAM);

if (connfd < 0) {

fprintf(stderr,

"client error:: could not create connected socket "

"socket\n");

return -1;

}

letter = '1';

m= write(connfd, &letter, sizeof(letter));

memset(timeStr, 0, sizeof(timeStr));

n = read(connfd,

timeStr,

sizeof(timeStr));

printf("%s\n", timeStr);

close(connfd);

return 0;

}

多播模式下的代碼:

服務端和客戶端共用 "mcastutil.cpp":

#include

#include

#include

#include

#include

#include

#include

#include

#include "mcastutil.h"

int

get_addr (const char *hostname,

const char *service,

int?????????family,

int?????????socktype,

struct sockaddr_storage *addr)

{

struct addrinfo hints, *res, *ressave;

int n, sockfd, retval;

retval = -1;

memset(&hints, 0, sizeof(struct addrinfo));

hints.ai_family = family;

hints.ai_socktype = socktype;

n = getaddrinfo(hostname, service, &hints, &res);

if (n <0) {

fprintf(stderr,

"getaddrinfo error:: [%s]\n",

gai_strerror(n));

return retval;

}

ressave = res;

sockfd=-1;

while (res) {

sockfd = socket(res->ai_family,

res->ai_socktype,

res->ai_protocol);

if (!(sockfd < 0)) {

if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0) {

close(sockfd);

memcpy(addr, res->ai_addr, sizeof(*addr);

retval=0;

break;

}

close(sockfd);

sockfd=-1;

}

res=res->ai_next;

}

freeaddrinfo(ressave);

return retval;

}

int

joinGroup(int sockfd, int loopBack, int mcastTTL,

struct sockaddr_storage *addr)

{

int r1, r2, r3, retval;

retval=-1;

switch (addr->ss_family) {

case AF_INET: {

struct ip_mreq??????mreq;

mreq.imr_multiaddr.s_addr=

((struct sockaddr_in *)addr)->sin_addr.s_addr;

mreq.imr_interface.s_addr= INADDR_ANY;

r1= setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,

&loopBack, sizeof(loopBack));

if (r1<0)

perror("joinGroup:: IP_MULTICAST_LOOP:: ");

r2= setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,

&mcastTTL, sizeof(mcastTTL));

if (r2<0)

perror("joinGroup:: IP_MULTICAST_TTL:: ");

r3= setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,

(const void *)&mreq, sizeof(mreq));

if (r3<0)

perror("joinGroup:: IP_ADD_MEMBERSHIP:: ");

} break;

case AF_INET6: {

struct ipv6_mreq????mreq6;

memcpy(&mreq6.ipv6mr_multiaddr,

&(((struct sockaddr_in6 *)addr)->sin6_addr),

sizeof(struct in6_addr));

mreq6.ipv6mr_interface= 0; // cualquier interfaz

r1= setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,

&loopBack, sizeof(loopBack));

if (r1<0)

perror("joinGroup:: IPV6_MULTICAST_LOOP:: ");

r2= setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,

&mcastTTL, sizeof(mcastTTL));

if (r2<0)

perror("joinGroup:: IPV6_MULTICAST_HOPS::??");

r3= setsockopt(sockfd, IPPROTO_IPV6,

IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6));

if (r3<0)

perror("joinGroup:: IPV6_ADD_MEMBERSHIP:: ");

} break;

default:

r1=r2=r3=-1;

}

if ((r1>=0) && (r2>=0) && (r3>=0))

retval=0;

return retval;

}

int

isMulticast(struct sockaddr_storage *addr)

{

int retVal;

retVal=-1;

switch (addr->ss_family) {

case AF_INET: {

struct sockaddr_in *addr4=(struct sockaddr_in *)addr;

retVal = IN_MULTICAST(ntohl(addr4->sin_addr.s_addr));

} break;

case AF_INET6: {

struct sockaddr_in6 *addr6=(struct sockaddr_in6 *)addr;

retVal = IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr);

} break;

default:

;

}

return retVal;

}

服務端 "mcastserver.cpp":

#include

#include

#include

#include

#include

#include

#include

#include

#include "mcastutil.h"

const char *DAYTIME_PORT="13";

int

main(int argc, char *argv[])

{

int sockfd, n;

char *mcastaddr;

char timeStr[256];

char b[256];

struct sockaddr_storage clientaddr, addr;

socklen_t addrlen;

time_t now;

char clienthost[NI_MAXHOST];

char clientservice[NI_MAXSERV];

mcastaddr = "FF01::1111";

if (argc ==2)

mcastaddr=argv[1];

memset(&addr, 0, sizeof(addr));

if (get_addr(mcastaddr, DAYTIME_PORT, PF_UNSPEC,

SOCK_DGRAM, &addr) <0)

{

fprintf(stderr, "get_addr error:: could not find multicast "

"address=[%s] port=[%s]\n", mcastaddr, DAYTIME_PORT);

return -1;

}

if (isMulticast(&addr)<0) {

fprintf(stderr,

"This address does not seem a multicast address [%s]\n",

mcastaddr);

return -1;

}

sockfd = socket(addr.ss_family, SOCK_DGRAM, 0);

if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {

perror("bind error:: ");

close(sockfd);

return -1;

}

if (joinGroup(sockfd, 0 , 8, &addr) <0) {

close(sockfd);

return -1;

}

addrlen=sizeof(clientaddr);

for ( ; ;) {

n = recvfrom(sockfd,

b,

sizeof(b),

0,

(struct sockaddr *)&clientaddr,

&addrlen);

if (n <0)

continue;

memset(clienthost, 0, sizeof(clienthost));

memset(clientservice, 0, sizeof(clientservice));

getnameinfo((struct sockaddr *)&clientaddr, addrlen,

clienthost, sizeof(clienthost),

clientservice, sizeof(clientservice),

NI_NUMERICHOST);

printf("Received request from host=[%s] port=[%s]\n",

clienthost, clientservice);

memset(timeStr, 0, sizeof(timeStr));

time(&now);

sprintf(timeStr, "%s", ctime(&now));

n = sendto(sockfd, timeStr, sizeof(timeStr), 0,

(struct sockaddr *)&addr,

sizeof(addr));

if (n<1)

perror("sendto error:: \n");

}

return 0;

}

客戶端 "mcastclient.cpp":

#include

#include

#include

#include

#include

#include

#include

#include "mcastutil.h"

const char *DAYTIME_PORT="13";

int

main(int argc, char *argv[])

{

int sockfd, n;

char *myhost;

char timeStr[256];

char letter;

struct sockaddr_storage addr, clientaddr;

int addrlen;

socklen_t clientaddrlen;

myhost = "FF01::1111";

if (argc == 2)

myhost=argv[1];

addrlen=sizeof(addr);

memset(&addr, 0, addrlen);

get_addr(myhost, DAYTIME_PORT, PF_UNSPEC, SOCK_DGRAM, &addr);

sockfd = socket(addr.ss_family, SOCK_DGRAM, 0);

if (bind(sockfd, (struct sockaddr *)&addr, addrlen) <0) {

perror("bind error:: \n");

close(sockfd);

return -1;

}

if (joinGroup(sockfd, 0 , 8, &addr) <0) {

close(sockfd);

return -1;

}

letter = '1';

n = sendto(sockfd, &letter, sizeof(letter), 0,

(struct sockaddr *)&addr,

addrlen);

if (n<0) {

perror("sendto error:: ");

close(sockfd);

return -1;

}

memset(timeStr, 0, sizeof(timeStr));

clientaddrlen=sizeof(clientaddr);

n = recvfrom(sockfd,

timeStr,

sizeof(timeStr),

0,

(struct sockaddr *)&clientaddr,

&clientaddrlen);

if (n<0) {

perror("sendto error:: ");

close(sockfd);

return -1;

}

printf("%s\n", timeStr);

close(sockfd);

return 0;

}

不使用主機名或DNS解析時怎么操作

????上面例子中都是用的主機名或者dns解析來得到具體地址的牺六,從hosts文件或者dns解析通過gethostbyname能得到具體的IPV6或IPV4地址陈莽,如下圖示:


內(nèi)核支持雙棧協(xié)議:

????如果要直接使用IPV6地址或IPV4地址,如果內(nèi)核支持雙棧協(xié)議(見下圖)寿烟,則只需要實現(xiàn)成ipv6地址操作即可澈驼,底層內(nèi)核會自動進行ipv6和ipv4地址的轉(zhuǎn)換

????客戶端代碼IPv6代碼(如果使用ipv4方式,則使用代碼中的注釋IPv4的代碼韧衣,同時注釋掉IPv6的代碼盅藻;另一種方式還是用ipv6代碼,但是服務器端的地址使用::ffff:a.b.c.d方式去進行連接):

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXBUF 1024

int main(int argc, char **argv)

{

int sockfd, len;

/* struct sockaddr_in dest; */// IPv4

struct sockaddr_in6 dest;// IPv6

char buffer[MAXBUF + 1];

if (argc != 3) {

printf

("參數(shù)格式錯誤畅铭!正確用法如下:/n/t/t%s IP地址 端口/n/t比如:/t%s 127.0.0.1 80/n此程序用來從某個 IP 地址的服務器某個端口接收最多 MAXBUF 個字節(jié)的消息",

argv[0], argv[0]);

exit(0);

}

/* 創(chuàng)建一個 socket 用于 tcp 通信 */

/* if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { */ // IPv4

if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {??????// IPv6

perror("Socket");

exit(errno);

}

printf("socket created/n");

/* 初始化服務器端(對方)的地址和端口信息 */

bzero(&dest, sizeof(dest));

/* dest.sin_family = AF_INET; */??// IPv4

dest.sin6_family = AF_INET6;?????// IPv6

/* dest.sin_port = htons(atoi(argv[2])); */ // IPv4

dest.sin6_port = htons(atoi(argv[2]));?????// IPv6

/* if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) { */ // IPv4 ?,argv[1]: 211.43.56.5

if ( inet_pton(AF_INET6, argv[1], &dest.sin6_addr) < 0 ) {?????????????????// IPv6 ?,argv[1]: 2001:f653:98d3::1

perror(argv[1]);

exit(errno);

}

printf("address created/n");

/* 連接服務器 */

if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {

perror("Connect ");

exit(errno);

}

printf("server connected/n");

/* 接收對方發(fā)過來的消息勃蜘,最多接收 MAXBUF 個字節(jié) */

bzero(buffer, MAXBUF + 1);

/* 接收服務器來的消息 */

len = recv(sockfd, buffer, MAXBUF, 0);

if (len > 0)

printf("接收消息成功:'%s'硕噩,共%d個字節(jié)的數(shù)據(jù)/n",

buffer, len);

else

printf

("消息接收失敗缭贡!錯誤代碼是%d炉擅,錯誤信息是'%s'/n",

errno, strerror(errno));

bzero(buffer, MAXBUF + 1);

strcpy(buffer, "這是客戶端發(fā)給服務器端的消息/n");

/* 發(fā)消息給服務器 */

len = send(sockfd, buffer, strlen(buffer), 0);

if (len < 0)

printf

("消息'%s'發(fā)送失敾岳痢!錯誤代碼是%d谍失,錯誤信息是'%s'/n",

buffer, errno, strerror(errno));

else

printf("消息'%s'發(fā)送成功眶俩,共發(fā)送了%d個字節(jié)!/n",

buffer, len);

/* 關(guān)閉連接 */

close(sockfd);

return 0;

}

服務器端代碼(同時支持IPv4和IPv6的客戶端來連接):

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXBUF 1024

int main(int argc, char **argv)

{

int sockfd, new_fd;

socklen_t len;

/* struct sockaddr_in my_addr, their_addr; */ // IPv4

struct sockaddr_in6 my_addr, their_addr; // IPv6

unsigned int myport, lisnum;

char buf[MAXBUF + 1];

if (argv[1])

myport = atoi(argv[1]);

else

myport = 7838;

if (argv[2])

lisnum = atoi(argv[2]);

else

lisnum = 2;

/* if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { */ // IPv4

if ((sockfd = socket(PF_INET6, SOCK_STREAM, 0)) == -1) { // IPv6

perror("socket");

exit(1);

} else

printf("socket created/n");

bzero(&my_addr, sizeof(my_addr));

/* my_addr.sin_family = PF_INET; */ // IPv4

my_addr.sin6_family = PF_INET6;????// IPv6

/* my_addr.sin_port = htons(myport); */ // IPv4

my_addr.sin6_port = htons(myport);???// IPv6

if (argv[3])

/* my_addr.sin_addr.s_addr = inet_addr(argv[3]); */ // IPv4

inet_pton(AF_INET6, argv[3], &my_addr.sin6_addr);??// IPv6

else

/* my_addr.sin_addr.s_addr = INADDR_ANY; */ // IPv4 ?,use 0.0.0.0

my_addr.sin6_addr = in6addr_any;????????????// IPv6 ? ? ? ? ? ,use ::

/* if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) */ // IPv4

if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_in6))??// IPv6

== -1) {

perror("bind");

exit(1);

} else

printf("binded/n");

if (listen(sockfd, lisnum) == -1) {

perror("listen");

exit(1);

} else

printf("begin listen/n");

while (1) {

len = sizeof(struct sockaddr);

if ((new_fd =

accept(sockfd, (struct sockaddr *) &their_addr,

&len)) == -1) {

perror("accept");

exit(errno);

} else

printf("server: got connection from %s, port %d, socket %d/n",

/* inet_ntoa(their_addr.sin_addr), */ // IPv4

inet_ntop(AF_INET6, &their_addr.sin6_addr, buf, sizeof(buf)), // IPv6

/* ntohs(their_addr.sin_port), new_fd); */ // IPv4

their_addr.sin6_port, new_fd); // IPv6

/* 開始處理每個新連接上的數(shù)據(jù)收發(fā) */

bzero(buf, MAXBUF + 1);

strcpy(buf,

"這是在連接建立成功后向客戶端發(fā)送的第一個消息/n只能向new_fd這個用accept函數(shù)新建立的socket發(fā)消息快鱼,不能向sockfd這個監(jiān)聽socket發(fā)送消息颠印,監(jiān)聽socket不能用來接收或發(fā)送消息/n");

/* 發(fā)消息給客戶端 */

len = send(new_fd, buf, strlen(buf), 0);

if (len < 0) {

printf

("消息'%s'發(fā)送失敗抹竹!錯誤代碼是%d线罕,錯誤信息是'%s'/n",

buf, errno, strerror(errno));

} else

printf("消息'%s'發(fā)送成功,共發(fā)送了%d個字節(jié)窃判!/n",

buf, len);

bzero(buf, MAXBUF + 1);

/* 接收客戶端的消息 */

len = recv(new_fd, buf, MAXBUF, 0);

if (len > 0)

printf("接收消息成功:'%s'钞楼,共%d個字節(jié)的數(shù)據(jù)/n",

buf, len);

else

printf

("消息接收失敗袄琳!錯誤代碼是%d询件,錯誤信息是'%s'/n",

errno, strerror(errno));

/* 處理每個新連接上的數(shù)據(jù)收發(fā)結(jié)束 */

}

close(sockfd);

return 0;

}

內(nèi)核只支持隔離棧(獨立棧)協(xié)議:


則無論是客戶端還是服務器端,都必須把ipv4和ipv6分開處理唆樊,客戶端不用說雳殊,使用哪類地址,就使用哪類代碼(參考上面雙棧協(xié)議實現(xiàn)中的注釋來支持ipv4)窗轩,服務器端通過建立兩個套接口夯秃,然后select檢測進來連接的客戶端是ipv4還是ipv6來同時支持ipv4或ipv6的連接

SOCKET ServSock[FD_SETSIZE];

ADDRINFO AI0, AI1;

ServSock[0] = socket(AF_INET6, SOCK_STREAM, PF_INET6);

ServSock[1] = socket(AF_INET, SOCK_STREAM, PF_INET);

...

bind(ServSock[0], AI0->ai_addr, AI0->ai_addrlen);

bind(ServSock[1], AI1->ai_addr, AI1->ai_addrlen);

...

select(2, &SockSet, 0, 0, 0);

if (FD_ISSET(ServSocket[0], &SockSet)) {

// IPv6 connection csock = accept(ServSocket[0], (LPSOCKADDR)&From, FromLen);

...

}

if (FD_ISSET(ServSocket[1], &SockSet))

// IPv4 connection csock = accept(ServSocket[1], (LPSOCKADDR)&From, FromLen);

...

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市痢艺,隨后出現(xiàn)的幾起案子仓洼,更是在濱河造成了極大的恐慌,老刑警劉巖堤舒,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件色建,死亡現(xiàn)場離奇詭異,居然都是意外死亡舌缤,警方通過查閱死者的電腦和手機箕戳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來国撵,“玉大人陵吸,你說我怎么就攤上這事〗檠溃” “怎么了壮虫?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我囚似,道長剩拢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任饶唤,我火速辦了婚禮徐伐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘募狂。我一直安慰自己办素,他們只是感情好,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布熬尺。 她就那樣靜靜地躺著摸屠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪粱哼。 梳的紋絲不亂的頭發(fā)上季二,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音揭措,去河邊找鬼胯舷。 笑死,一個胖子當著我的面吹牛绊含,可吹牛的內(nèi)容都是我干的桑嘶。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼躬充,長吁一口氣:“原來是場噩夢啊……” “哼逃顶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起充甚,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤以政,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后伴找,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盈蛮,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年技矮,在試婚紗的時候發(fā)現(xiàn)自己被綠了抖誉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡衰倦,死狀恐怖袒炉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耿币,我是刑警寧澤梳杏,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站淹接,受9級特大地震影響十性,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜塑悼,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一劲适、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厢蒜,春花似錦霞势、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至巷屿,卻和暖如春固以,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嘱巾。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工憨琳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人旬昭。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓篙螟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親问拘。 傳聞我的和親對象是個殘疾皇子遍略,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容