full cone的验证

本文介绍了一个简单的UDP测试工具,该工具支持客户端与服务器之间的UDP消息发送与接收功能。客户端能够向指定的IP和端口发送UDP消息,并从服务器接收响应;服务器端则监听特定端口并处理接收到的消息。

1. 内部进程甲和乙是向相同的IP/port发送报文,在Modem的Wan侧镜像,看目的地址的端口号如何变化。
2. 根据这个端口号,在服务器上初始化外部进程A用于收包,向该IP/port回应一个包。在内部主机上面抓包,可以收到这个包。
3. 外部主机进程A向B共享WAN侧IP和端口号,进程B向该IP/port回应包。
----------
udptest
1. 启动该进程后,陷入死循环,接受用户输入的命令
2. send命令,向某个端口号发送消息
3. receive命令,启动一个线程,监控某个端口号,接收消息。线程超时期为10分钟。
4. set命令,设置进程使用的IP地址。

 

要能够模拟BT。

 

 


 

sscanf(ip_port, "%[0-9.]:%hu", ip, &port) ;

 

 

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define BUFLEN 512
#define COMMANDLEN 10
#define MSGBUFF 1524

int help(char *para) ;
int client(char *ip_port) ;
int server(char *port) ;

typedef int (*ut_handle)(char *para) ;
struct ut_option
{
    char comm[COMMANDLEN] ;
    ut_handle handle ;
};

struct ut_option options[] = {
    {"help", help},
    {"sendto", client},
    {"recvfrom", server}
} ;

int help(char *para)
{
    printf("/tsendto ip:port/n") ;
    printf("/trecvfrom port/n") ;
    printf("/thelp/n/n") ;
    return 0 ;
}

int client(char *ip_port)
{
    int sockfd ;
    unsigned short port ;
    unsigned char ip[20] ;
    struct sockaddr_in servaddr, cliaddr ;
    char msg[BUFLEN] ;
    int len, recvlen ;

    sscanf(ip_port, "%[0-9.]:%hu", ip, &port) ;
    bzero(&servaddr, sizeof(servaddr)) ;
    servaddr.sin_family = AF_INET ;
    servaddr.sin_port = htons(port) ;
    if(inet_pton(AF_INET, ip, &servaddr.sin_addr) <= 0)
    {
        printf("%s is not a valid ip address/n", ip) ;
        return -1 ;
    }
    sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
    if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)))
    {
        printf("connect error/n") ;
        return -1 ;
    }
    sendto(sockfd, msg, BUFLEN, 0, (struct sockaddr*)&servaddr, sizeof(servaddr)) ;
    while(1)
    {
        recvlen = recvfrom(sockfd, msg, BUFLEN, 0, (struct sockaddr*)&cliaddr, &len) ;
        printf("recv a msg from %s:%u, len=%d/n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port), recvlen) ;
    }
}

void* server_thread(void *port)
{
    int sockfd ;
    unsigned int uport ;
    struct sockaddr_in servaddr, cliaddr;
    char msg[BUFLEN] ;
    int len, recvlen ;

    sscanf(port, "%u", &uport) ;
    sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
    bzero(&servaddr, sizeof(servaddr)) ;
    servaddr.sin_family = AF_INET ;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY) ;
    servaddr.sin_port = htons(uport) ;
    if(bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    {
        perror("bind error") ;
        exit(1) ;
    }
    while(1)
    {
        recvlen = recvfrom(sockfd, msg, BUFLEN, 0, (struct sockaddr*)&cliaddr, &len) ;
        printf("recv a msg from %s:%u, len=%d/n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port), recvlen) ;
    }
    return 0 ;
}

int server(char *port)
{
   pthread_t tid ;
   int err ;

    err = pthread_create(&tid, NULL, server_thread, port) ;
    if(err != 0)
        printf("can't not create thread:%s/n", strerror(err)) ;
    printf("created a new thread[%u] on port %s/n", (unsigned int)tid, port) ;

    return 0 ;
}

int main()
{
    char line[BUFLEN] ;
    char command[COMMANDLEN] ;
    char paras[BUFLEN - COMMANDLEN - 2] ;
    int size = 0 ;
    int optlen = sizeof(options)/sizeof(struct ut_option) ;
    while( 1 )
    {
        int i ;
        printf(">") ;
        gets(line) ;
        if(line[0] == '/0')
            continue ;
        sscanf(line, "%s %s", command, paras) ;
        for(i = 0; i < optlen; i++)
        {
            if(!strcmp(options[i].comm, command))
                break ;
        }
        if(i == optlen)
            printf("not supported command/n") ;

        options[i].handle(paras) ;
        memset(line, 0, COMMANDLEN) ;
    }

    return 0 ;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值