Skip to content

天楚锐齿

人工智能 云计算 大数据 物联网 IT 通信 嵌入式

天楚锐齿

  • 下载
  • 物联网
  • 云计算
  • 大数据
  • 人工智能
  • Linux&Android
  • 网络
  • 通信
  • 嵌入式
  • 杂七杂八

用c/c++语言在IPv6下的socket通信编程

2018-03-15

下面为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地址,如下图示:

 

内核支持双栈协议:

如果要直接使用IPV6地址或IPV4地址,如果内核支持双栈协议(见下图),则只需要实现成ipv6地址操作即可,底层内核会自动进行ipv6和ipv4地址的转换:

 
 

    客户端代码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

(“参数格式错误!正确用法如下:/n/t/t%s IP地址 端口/n/t比如:/t%s 127.0.0.1 80/n此程序用来从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息”,

argv[0], argv[0]);

exit(0);

}

/* 创建一个 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”);

/* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */

bzero(buffer, MAXBUF + 1);

/* 接收服务器来的消息 */

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

if (len > 0)

printf(“接收消息成功:’%s’,共%d个字节的数据/n”,

buffer, len);

else

printf

(“消息接收失败!错误代码是%d,错误信息是’%s’/n”,

errno, strerror(errno));

bzero(buffer, MAXBUF + 1);

strcpy(buffer, “这是客户端发给服务器端的消息/n”);

/* 发消息给服务器 */

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

if (len < 0)

printf

(“消息’%s’发送失败!错误代码是%d,错误信息是’%s’/n”,

buffer, errno, strerror(errno));

else

printf(“消息’%s’发送成功,共发送了%d个字节!/n”,

buffer, len);

/* 关闭连接 */

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

/* 开始处理每个新连接上的数据收发 */

bzero(buf, MAXBUF + 1);

strcpy(buf,

“这是在连接建立成功后向客户端发送的第一个消息/n只能向new_fd这个用accept函数新建立的socket发消息,不能向sockfd这个监听socket发送消息,监听socket不能用来接收或发送消息/n”);

/* 发消息给客户端 */

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

if (len < 0) {

printf

(“消息’%s’发送失败!错误代码是%d,错误信息是’%s’/n”,

buf, errno, strerror(errno));

} else

printf(“消息’%s’发送成功,共发送了%d个字节!/n”,

buf, len);

bzero(buf, MAXBUF + 1);

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

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

if (len > 0)

printf(“接收消息成功:’%s’,共%d个字节的数据/n”,

buf, len);

else

printf

(“消息接收失败!错误代码是%d,错误信息是’%s’/n”,

errno, strerror(errno));

/* 处理每个新连接上的数据收发结束 */

}

close(sockfd);

return 0;

}

内核只支持隔离栈(独立栈)协议:

 

则无论是客户端还是服务器端,都必须把ipv4和ipv6分开处理,客户端不用说,使用哪类地址,就使用哪类代码(参考上面双栈协议实现中的注释来支持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);

…

}

 

1,168次阅读

Post navigation

前一篇:

在Windows上使用Teredo隧道上IPV6网站

后一篇:

用java语言在IPV6下的socket通信编程

发表评论 取消回复

邮箱地址不会被公开。 必填项已用*标注

个人介绍

需要么,有事情这里找联系方式:关于天楚锐齿

=== 美女同欣赏,好酒共品尝 ===

微信扫描二维码赞赏该文章:

扫描二维码分享该文章:

分类目录

  • Linux&Android (79)
  • Uncategorized (1)
  • 下载 (28)
  • 云计算 (37)
  • 人工智能 (8)
  • 大数据 (24)
  • 嵌入式 (34)
  • 杂七杂八 (34)
  • 物联网 (59)
  • 网络 (23)
  • 通信 (21)

文章归档

近期文章

  • 使用Python渲染OpenGL的.obj和.mtl文件
  • 用LVGL图形库绘制二维码
  • Android使用Messenger和SharedMemory实现跨app的海量数据传输
  • CAN信号的c语言解析代码
  • QT qml下DBus的使用例子

近期评论

  • 硕发表在《使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序》
  • maxshu发表在《使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序》
  • Ambition发表在《使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序》
  • Ambition发表在《使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序》
  • maxshu发表在《Android9下用ethernet 的Tether模式来做路由器功能》

阅读量

  • 使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序 - 16,806次阅读
  • 卸载深信服Ingress、SecurityDesktop客户端 - 12,078次阅读
  • 车机技术之Android Automotive - 6,661次阅读
  • 车机技术之车规级Linux-Automotive Grade Linux(AGL) - 5,861次阅读
  • Linux策略路由及iptables mangle、ip rule、ip route关系及一种Network is unreachable错误 - 5,711次阅读
  • 在Android9下用ndk编译vSomeIP和CommonAPI以及使用例子 - 5,658次阅读
  • linux下的unbound DNS服务器设置详解 - 5,601次阅读
  • linux的tee命令导致ssh客户端下的shell卡住不动 - 4,998次阅读
  • 车机技术之360°全景影像(环视)系统 - 4,897次阅读
  • libwebp(处理webp图像)的安装和使用 - 4,749次阅读

功能

  • 文章RSS
  • 评论RSS

联系方式

地址
深圳市科技园

时间
周一至周五:  9:00~12:00,14:00~18:00
周六和周日:10:00~12:00

标签

android AT命令 centos Hadoop hdfs ip ipv6 kickstart linux mapreduce mini6410 modem OAuth openstack os python socket ssh uboot 内核 协议 安装 嵌入式 性能 报表 授权 操作系统 数据 数据库 月报 模型 汽车 测试 深信服 深度学习 源代码 神经网络 统计 编译 网络 脚本 虚拟机 调制解调器 车机 金融
© 2023 天楚锐齿