网上关于udp打洞都是一些C#的例子,而且写得比较复杂,写了个简单的测试程序,测试通过,但是在客户端在同一个内网此种方法无效,另外udp会丢包,如果一次执行不成功,可以多执行几次。
server.c
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <errno.h>
- #include <string.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <stdio.h>
- int main(int argc, const char *argv[])
- {
- int fd = socket(AF_INET, SOCK_DGRAM, 0);
- if( fd < 0 )
- {
- printf("socket error: %s\n", strerror(errno));
- return 1;
- }
- struct sockaddr_in sa;
- memset(&sa, 0, sizeof(sa));
- sa.sin_family = AF_INET;
- sa.sin_port = htons(10000);
- sa.sin_addr.s_addr = INADDR_ANY;
- int ret = bind(fd, (struct sockaddr *)&sa, sizeof(sa));
- if( ret < 0 )
- {
- printf("bind error: %s\n", strerror(errno));
- return 1;
- }
- struct sockaddr_in ca[2];
- memset(&ca, 0, sizeof(ca));
- char buff[100];
- socklen_t slen;
- int i = 0;
- ssize_t size;
- for(; i < 2; i++)
- {
- size = recvfrom(fd, &buff, sizeof(buff), 0, (struct sockaddr *)&(ca[i]), &slen);
- if( size < 0 )
- {
- printf("recvfrom error: %s\n", strerror(errno));
- return 1;
- }
- printf("recvfrom ip: %s, port: %d\n", inet_ntoa(ca[i].sin_addr), ntohs(ca[i].sin_port));
- }
- size = sendto(fd, &ca[0], sizeof(ca[0]), 0, (struct sockaddr *)&ca[1], sizeof(ca[1]));
- if ( size < 0 )
- {
- printf("sendto error: %s\n", strerror(errno));
- return 1;
- }
- size = sendto(fd, &ca[1], sizeof(ca[1]), 0, (struct sockaddr *)&ca[0], sizeof(ca[0]));
- if ( size < 0 )
- {
- printf("sendto error: %s\n", strerror(errno));
- return 1;
- }
- return 0;
- }
client.c
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- int main(int argc, const char *argv[])
- {
- int fd = socket(AF_INET, SOCK_DGRAM, 0);
- if( fd < 0 )
- {
- printf("socket error: %s\n", strerror(errno));
- return 1;
- }
- struct sockaddr_in sa;
- memset(&sa, 0, sizeof(sa));
- sa.sin_family = AF_INET;
- sa.sin_port = htons(10000);
- sa.sin_addr.s_addr = inet_addr("xx.xx.xx.xx");
- char *p = "a";
- ssize_t size = sendto(fd, p, 1, 0, (struct sockaddr *)&sa, sizeof(sa));
- if( size < 0 )
- {
- printf("sendto error: %s\n", strerror(errno));
- return 1;
- }
- printf("send ok recv now\n");
- char buff[100];
- struct sockaddr_in ca;
- socklen_t slen;
- memset(&ca, 0, sizeof(ca));
- size = recvfrom(fd, buff, sizeof(buff), 0, (struct sockaddr *)&ca, &slen);
- if( size < 0 )
- {
- printf("recvfrom error: %s\n", strerror(errno));
- return 1;
- }
- struct sockaddr_in *ps = (struct sockaddr_in *)buff;
- printf("recv another client ip: %s, port: %d\n", inet_ntoa(ps->sin_addr), ntohs(ps->sin_port));
- int i;
- for( i = 0; i < 3; i++ )
- {
- printf("send %d times\n", i);
- p = "hello world";
- ps->sin_family = AF_INET;
- size = sendto(fd, p, strlen(p), 0, (struct sockaddr *)ps, sizeof(struct sockaddr_in));
- if( size < 0 )
- {
- printf("sendto error: %s\n", strerror(errno));
- return 1;
- }
- printf("send %d times ok, recv now\n", i);
- char buf[100] = {0};
- struct sockaddr_in ca1;
- memset(&ca1, 0, sizeof(ca1));
- size = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&ca1, &slen);
- if( size < 0 )
- {
- printf("recvfrom error: %s\n", strerror(errno));
- return 1;
- }
- printf("recv %d message: %s\n", i, buf);
- sleep(1);
- }
- return 0;
- }
阅读(6602) | 评论(0) | 转发(0) |