版权声明:转载请标明出处。
本篇为记录linux socket支持ipv6的学习笔记,ipv6的tcp socket编程与ipv4并无过多差别,主要有两点:
1、在协议结构体上面有些差别;
2、tcp的客户端必须用setsockopt进行绑定网卡才能成功发送消息。
详细的请看代码。
tcp服务端程序:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MAXBUF 1024
int main(int argc, char **argv)
{
int sockfd, new_fd;
socklen_t len;
struct sockaddr_in6 my_addr, their_addr;
unsigned int myport, lisnum;
char buf[MAXBUF + 1];
myport = 8888;
lisnum = 2;
if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
} else
printf("socket created\n");
bzero(&my_addr, sizeof(my_addr));
my_addr.sin6_family = AF_INET6;
my_addr.sin6_port = htons(myport);
if (argv[1])
inet_pton(AF_INET6, argv[1], &my_addr.sin6_addr);
else
my_addr.sin6_addr = in6addr_any;
if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_in6))== -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_in6);
if ((new_fd = accept(sockfd, (struct sockaddr *) &their_addr,&len)) == -1) {
perror("accept");
exit(errno);
} else
{
char buf_r[1024] ="";
inet_ntop(AF_INET6, &their_addr.sin6_addr, buf_r, sizeof(buf_r));
printf("server: connection from [%s], port %d, socket %d\n", buf_r, their_addr.sin6_port, new_fd);
}
bzero(buf, MAXBUF + 1);
strcpy(buf, "hello!!");
/* 发消息给客户端 */
len = send(new_fd, buf, strlen(buf), 0);
if (len < 0)
printf("send failed [%s], [%d] [%s]\n",buf, errno, strerror(errno));
else
printf("send success [%s] [%d]\n", buf, len);
bzero(buf, MAXBUF + 1);
/* 接收客户端的消息 */
len = recv(new_fd, buf, MAXBUF, 0);
if (len > 0)
printf("recv success [%s] [%d]\n", buf, len);
else
printf("recv fail! [%d],[%s]\n", errno, strerror(errno));
}
close(sockfd);
return 0;
}
tcp客户端程序:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#define MAXBUF 1024
int main(int argc, char **argv)
{
int sockfd, len;
struct sockaddr_in6 dest;
char buffer[MAXBUF + 1];
char buf[1024] = "";
if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
perror("Socket failed");
exit(errno);
}
printf("socket created\n");
//绑定网卡eth0
setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", sizeof("eth0"));
bzero(&dest, sizeof(dest));
dest.sin6_family = AF_INET6;
dest.sin6_port = htons(8888);
if ( inet_pton(AF_INET6, argv[1], &dest.sin6_addr) < 0 ) {
perror(argv[1]);
exit(errno);
}
inet_ntop(AF_INET6, &dest.sin6_addr, buf, sizeof(buf));
printf("%s\n", buf);
printf("address created\n");
/* 连接服务器 */
if (connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) != 0) {
printf("fail.[%s], [%d] sockfd is %d\n",strerror(errno), errno, sockfd);
exit(errno);
}
printf("server connected\n");
bzero(buffer, MAXBUF + 1);
/* 接收服务器来的消息 */
len = recv(sockfd, buffer, MAXBUF, 0);
if (len > 0)
printf("recv success [%s] [%d]\n", buffer, len);
else
printf("recv fail! [%d],[%s]\n", errno, strerror(errno));
bzero(buffer, MAXBUF + 1);
strcpy(buffer, "how old are you");
/* 发消息给服务器 */
len = send(sockfd, buffer, strlen(buffer), 0);
if (len < 0)
printf
("send [%s] fail [%d] [%s]\n", buffer, errno, strerror(errno));
else
printf("send success [%s] [%d]\n", buffer, len);
close(sockfd);
return 0;
}