小弟刚刚接触网络编程,前两天看了UDP打洞原理与实践一问,颇有感触。随即付诸实践,但之后了解到公司防火墙对UDP以大多数端口号的包都进行了拦截,看来通过UDP打洞是无法实现两个内网IP互相通讯了。
于是我想还是从头开始用一台公网机器作转发,来对两台机器通信。创建TCP类型的socket,端口80,想来这样防火墙应该能够通过。
实验开始:内网客户端和公网的服务器能够连接,内网客户端能够接收到公网客户端发送的消息(通过一公网服务器转发),但内网机器发出的任何命令都没有相应,并返回recv() error(SOCKET_ERROR), 请教各位高手能否帮忙分析一下(程序原因或是与内网防火墙的原因)。

解决方案 »

  1.   

    服务器有没有接收到数据??客户端发送send有没有成功???
      

  2.   

    实验环境是这样:
    公网机器A, 公网机器B, 内网机器C
    A上运行server.exe和client.exe
    B上运行client.exe
    C上运行client.exe三台机器的Client都能够连接到server
    Client(A) -> Client(B)或Client(A) -> Client(C) 都能够通过server(A)转发消息
    Client(B) -> Client(A)也能够通过server(A)转发
    但是Client(C)->Client(A)确未能成功,服务器没收到任何消息,client(C)也没收到任何消息
    Client(C)上显示recv()错误(SOCKET_ERROR)由于需要多个人帮忙,往往对出错现象也不是很明确。只能靠大家分析了。
      

  3.   

    有可能是内网的NAT不支持内-外-内的转换,只能转到外网,一旦发现需要转出去的包的目的地IP是内网的,很多NAT会直接丢弃掉。
      

  4.   

    补充说明, 我使用的是最基本的阻塞方式的api调用
    现在得到错误代码为WSAECONNRESET(10054)
    Connection reset by peer. 
    An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket.) This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET. 
    服务器端应不会hard close, 那位能帮忙解释一下其他原因,在线急等!!!另外请教看到书上说TCP所谓的基于"流"的协议,那么客户端连续两个send, 服务器段连续两个recv能分别得到相应的buffer内容么??
      

  5.   


    "可以通过数据头来解决数据是那一个的问题" 不是很明白。另外这个问题和socket选项的SO_KEEPALIVE有什么关系么??
      

  6.   

    但是Client(C)->Client(A)确未能成功,服务器没收到任何消息,client(C)也没收到任何消息
    ——————————————————————————————————————————
    内网计算机访问不了外网,一般不太可能啊。
    公司的防火墙给过滤了。