免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2508 | 回复: 8
打印 上一主题 下一主题

NAT穿越问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-10-17 11:17 |只看该作者 |倒序浏览
协议全部采用udp        

        客户端在私网,首先对在公网的服务器发送一个数据包,然后一直接收数据;

        服务器在公网上,bind了一个端口,等待连接,有连接后,保存连接者的IP和端口,然后又建了一个
socket对这个端口发送数据,为什么发不通啊?

论坛徽章:
39
2017金鸡报晓
日期:2017-02-08 10:39:4219周年集字徽章-周
日期:2023-04-15 12:02:2715-16赛季CBA联赛之深圳
日期:2023-02-16 14:39:0220周年集字徽章-年
日期:2022-08-31 14:25:28黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:27
2 [报告]
发表于 2006-10-17 13:09 |只看该作者
上下调整一个端口号试试。

论坛徽章:
0
3 [报告]
发表于 2006-10-18 16:11 |只看该作者
服务器在公网上,bind了一个端口,等待连接,有连接后,保存连接者的IP和端口,然后又建了一个
socket对这个端口发送数据,为什么发不通啊?


你这里又建了一个socket是什么意思?是又bind了一个端口还是?如果又bind了一个端口那就要告诉客户端新端口

论坛徽章:
0
4 [报告]
发表于 2006-10-19 09:50 |只看该作者
没有绑定端口,就是新建了一个udp socket,给保存的那个地址发送数据,数据是服务器新建的udp socket主动发的,发不通

论坛徽章:
0
5 [报告]
发表于 2006-10-19 09:52 |只看该作者
很奇怪,P2P不也就是服务器保存连接者的地址,然后告诉每个客户端这个地址,互相打洞实现的

这个为什么不能?

论坛徽章:
0
6 [报告]
发表于 2006-10-19 10:03 |只看该作者
客户端测试代码:  在私网

#include <iostream>
using namespace std;
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>  
#include <netdb.h>
#include <unistd.h>

struct sockaddr_in Get_ServerAddr(char *ip,int port)
{
     struct hostent *host;
     struct sockaddr_in ServerAddr1;
     bzero(&(ServerAddr1.sin_zero),8);
     ServerAddr1.sin_family =AF_INET;
     ServerAddr1.sin_port =htons(port);

    if(inet_aton(ip,&ServerAddr1.sin_addr)==0)        //假如是域名
   {
                host=gethostbyname(ip);
                if(host==NULL)
                {
                        cout<<"不合法的域名"<<endl;
                }
                if(host->h_addrtype!=AF_INET)
                {
                        cout<<"不合法的域名"<<endl;
                }
                ServerAddr1.sin_addr=*(struct in_addr *)(host->h_addr_list[0]);
     
   }
   return ServerAddr1;
}

int main()
{
    int fd=socket(AF_INET,SOCK_DGRAM, 0);
    struct sockaddr_in  fLocalAddr,ServerAddr,remote;
   
    memset(&fLocalAddr, 0, sizeof(fLocalAddr));
    fLocalAddr.sin_family = AF_INET;
    fLocalAddr.sin_port = htons(8080);
    fLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);   
   
    char buf[1024];
     int len;
    ServerAddr=Get_ServerAddr("218.28.20.150",8080);
    int n;
   
    socklen_t fromlen = sizeof(ServerAddr);
    strcpy(buf,"hello\r\n");
   

   
     int err =bind(fd,(sockaddr *)&fLocalAddr, sizeof(fLocalAddr));
   
      sendto(fd,buf, strlen(buf), 0, (const struct sockaddr*)&ServerAddr,sizeof(ServerAddr));
            //先给服务器发送一个消息
      fd_set rfds;
   
   
   
    FD_ZERO(&rfds);
    FD_SET(fd,&rfds);
    while(1)
    {
           FD_ZERO(&rfds);
           FD_SET(fd,&rfds);
           select(fd+1,&rfds,NULL,NULL,NULL);                     //然后一直接收
           
          len=recvfrom(fd,buf,1023,0,(sockaddr *)&remote,&fromlen);        
         
          buf[len]='\0';      
          cout<<"recv:   "<<buf<<endl;
          cout<<"ip======="<<inet_ntoa(remote.sin_addr)<<"   port===="<<ntohs(remote.sin_port)<<endl;         
           
                   
    }
   
    return 0;
}



服务器端测试代码:  在公网


#include <iostream>
using namespace std;

#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>  
#include <netdb.h>
#include <unistd.h>



struct sockaddr_in  fLocalAddr,remote,fLocalAddr1;

pthread_t tt;

void *t_main(void *arg)
{
    char buf1[1024];   
   
    strcpy(buf1,"22222222222222222222222222222222222222\r\n");
   
    int fd=socket(AF_INET,SOCK_DGRAM, 0);                          //新建了socket,也对那个地址发,但是对方收不到      
  /*  memset(&fLocalAddr1, 0, sizeof(fLocalAddr1));                //bind 不 bind 无所谓吧?
    fLocalAddr1.sin_family = AF_INET;
    fLocalAddr1.sin_port = htons(8081);
    fLocalAddr1.sin_addr.s_addr = htonl(INADDR_ANY);
    int err =bind(fd,(sockaddr *)&fLocalAddr1, sizeof(fLocalAddr1));*/
   
    while(1)
    {
        memset(buf1,0,1024);
        strcpy(buf1,"22222222222222222222222222222222222222\r\n");
        sendto(fd,buf1, strlen(buf1), 0, (const struct sockaddr*)&remote,sizeof(remote));
        sleep(1);
     }
     
}


int main()
{
    int fd1=socket(AF_INET,SOCK_DGRAM, 0);
   
   
    memset(&fLocalAddr, 0, sizeof(fLocalAddr));
    fLocalAddr.sin_family = AF_INET;
    fLocalAddr.sin_port = htons(8080);
    fLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    int err =bind(fd1,(sockaddr *)&fLocalAddr, sizeof(fLocalAddr));
    char buf[10240];
   
    socklen_t fromlen = sizeof(fLocalAddr);
   
     int len;
   
     len=recvfrom(fd1,buf,10230,0,(sockaddr *)&remote,&fromlen);     //服务器先接收客户端一个消息,保存它的地址
     
     buf[len]='\0';        
     cout<<"ip======="<<inet_ntoa(remote.sin_addr)<<"   port===="<<ntohs(remote.sin_port)<<endl;;      
     strcpy(buf,"1111111111111111111111111111111\r\n");      
     pthread_create(&tt,NULL,&t_main,NULL);  
   
   
    while(1)
    {  
             sendto(fd1,buf, strlen(buf), 0, (const struct sockaddr*)&remote,sizeof(remote));
                                              //接收客户端消息的那个socket可以回复发通
           sleep(1);
   
    }
   
    return 0;
}

[[i] 本帖最后由 lvliangliang 于 2006-10-19 10:04 编辑 [/i]]

论坛徽章:
0
7 [报告]
发表于 2006-10-19 10:07 |只看该作者
因为你服务器新建的SOCKET还没打洞,
所以NAT不给你通

论坛徽章:
0
8 [报告]
发表于 2006-10-19 10:16 |只看该作者
谢谢楼上的
我该怎么去打洞?

论坛徽章:
0
9 [报告]
发表于 2006-10-19 10:17 |只看该作者
服务器新建的SOCKET一直在对客户端发送数据
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP