|
话不多说,直接上源码。- /**
- *@author walker
- *@date 2012.9
- */
-
- #include <unistd.h>
- #include <arpa/inet.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define UDP_PORT 6000 //预定义的端口号
- #define MAXSIZE 8192
-
- //实际使用端口号
- int g_udp_port = UDP_PORT;
-
- //用于回显的函数
- void echo_fn(int sockfd);
-
- int main(int argc, char *argv[])
- {
- //获取用户输入的端口号
- if (argc > 1)
- {
- g_udp_port = atoi(argv[1]);
- }
- if (g_udp_port <= 0 || g_udp_port > 65535)
- {
- perror("Invalid port.\n");
- return -1;
- }
-
- int sockfd; //套接字描述符
- struct sockaddr_in6 addr; //用于UDP的IPv6地址结构
-
- if((sockfd = socket(AF_INET6, SOCK_DGRAM,0)) == -1)
- {
- printf("Error in socket\n");
- return -1;
- }
-
- bzero(&addr, sizeof(addr));
- addr.sin6_family = AF_INET6;
- addr.sin6_port = htons(g_udp_port);
- addr.sin6_addr = in6addr_any;
-
- if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) == -1)
- {
- printf("Error in binding\n");
- return -1;
- }
-
- echo_fn(sockfd); //调用回显函数
-
- close(sockfd); //关闭套接字
-
- return -1;
- }
-
- //用于回显的函数
- void echo_fn(int sockfd)
- {
- char data[MAXSIZE];
- int n = 0;
- socklen_t len = sizeof(struct sockaddr_in6);
- struct sockaddr_in6 addr;
-
- while(1)
- {
- printf("Waiting for data...\n");
-
- //接受从客户端发来的数据
- if((n = recvfrom(sockfd, data, MAXSIZE, 0, (struct sockaddr *)&addr, &len)) == -1)
- {
- printf("Error in receiving\n");
- exit(-1);
- }
- data[n] = '\0';
-
- printf("Received data: %s\n", data);
- //将收到的数据再发送回去
- sendto(sockfd, data, n, 0, (struct sockaddr *)&addr, len);
-
- //存储用"冒号十六进制记法"表示的IPv6地址
- char buf_addr[40];
- //将IPv6地址转为"冒号十六进制记法"(colon hexadecimal notation)表示
- inet_ntop(AF_INET6, &addr.sin6_addr, buf_addr, 64);
-
- printf("Client ip: %s\n", buf_addr);
- printf("Client port: %d\n", ntohs(addr.sin6_port));
- printf("\n");
- }
- }
|
|
|