小弟在试着开发一个即时聊天的东东,现在是内网(ip:192.168.0.112)能访问到外网(61.144.60.16),也就是说能发信息到61.144.60.16这台服务器,当服务器接收到信息后,返回信息给内网时客户端的client.Receive(ref remotePoint)没有任何反应,也没有报错,具体代码码如下服务器端server:
private void Run()
{
byte[] buffer = null;         byte[] msgBuffer = server.Receive(ref remotePoint);
         object msgObj = FormatterHelper.Deserialize(msgBuffer);
Type msgType = msgObj.GetType();
if (msgType == typeof(LoginMessage))
{
            LoginMessage _LoginMessage=new LoginMessage();
            buffer = FormatterHelper.Serialize(_LoginMessage);
            server.Send(buffer, buffer.Length, this.remotePoint);
          }
}
客户端client
public void ConnectToServer(string fromuserid , string fromusername)
{
LoginMessage lginMsg = new LoginMessage();
byte[] buffer = FormatterHelper.Serialize(lginMsg);
client.Send(buffer, buffer.Length, hostPoint);
buffer = client.Receive(ref remotePoint);//**********到这就没反应了

}

解决方案 »

  1.   

    看看你的gateway端设置,是否屏蔽了此端口信息
      

  2.   

    楼主你这个属于是p2p通讯问题,当外网要访问内网的主机(192.168.0.112)时,内网的主机(192.168.0.112)首先要在内网的NAT上建立一个Session,而且这个Session是有方向的.比如内网主机(192.168.0.112)向外部服务器(这里假设为61.144.60.16)发送一个UDP包,那么内网主机(192.168.0.112)就在内网的NAT设备上建立了一个方向为61.144.60.16的Session,以后外部服务器(61.144.60.16)就可以通过这个Session与内网的主机(192.168.0.112)联系了,而且其他的IP不能利用这个Session。所以估计楼主程序在外服务器收到消息后,回发到内部主机时,内部主机没有在相应的端口上同NAT设备建立Session,造成内网的NAT设备把收到来自外部服务器的消息丢弃,这样内部网主机当然会没反应了。
      

  3.   


    //-----------------------------客户端类
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    //using System.Text.RegularExpressions; 
    //using System.IO;
    namespace MyClient
    {
    /// <summary>
    /// client 的摘要说明。
    /// </summary>
    public class client
    {
    public client()
    {
    //
    // TODO: 在此处添加构造函数逻辑
    //
    }
    public static void StartClient(string IPstr,int IPport,string sendStr) 
    {
    //sendStr="这是来自客户端的信号!!!";
    // Data buffer for incoming data.
    byte[] bytes = new byte[1024]; // Connect to a remote device.
    try 
    {
    // Establish the remote endpoint for the socket.
    // The name of the
    // remote device is "host.contoso.com".
    //IPstr="192.168.0.124";
    //IPport=Convert.ToInt32(11100);
    IPHostEntry ipHostInfo = Dns.Resolve(IPstr);
    IPAddress ipAddress = ipHostInfo.AddressList[0];
    IPEndPoint remoteEP = new IPEndPoint(ipAddress,IPport); // Create a TCP/IP  socket.
    Socket sender = new Socket(AddressFamily.InterNetwork, 
    SocketType.Stream, ProtocolType.Tcp ); // Connect the socket to the remote endpoint. Catch any errors.
    try 
    {
    sender.Connect(remoteEP); Console.WriteLine("Socket connected to {0}",sender.RemoteEndPoint.ToString()); //MessageBox.Show("Socket connected to "+sender.RemoteEndPoint.ToString()); // Encode the data string into a byte array.

    byte[] msg = Encoding.UTF8.GetBytes(sendStr+"<EOF>"); // Send the data through the socket.
    int bytesSent = sender.Send(msg); // Receive the response from the remote device.
    int bytesRec = sender.Receive(bytes);

    Console.WriteLine("Echoed test = {0}",Encoding.UTF8.GetString(bytes,0,bytesRec));
    //MessageBox.Show("Echoed test = "+Encoding.UTF8.GetString(bytes,0,bytesRec)); //iReturn(Encoding.UTF8.GetString(bytes,0,bytesRec)); // Release the socket.
    sender.Shutdown(SocketShutdown.Both);
    sender.Close();
                    

    catch (ArgumentNullException ane) 
    {
    Console.WriteLine("ArgumentNullException : "+ane.ToString());

    catch (SocketException se) 
    {
    Console.WriteLine("SocketException : "+se.ToString());

    catch (Exception e) 
    {
    Console.WriteLine("Unexpected exception : "+e.ToString());
    } } 
    catch (Exception e) 
    {
    Console.WriteLine( e.ToString());
    }
    } }
    }//--------------服务端类
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    namespace MyServer
    {
    public class SynchronousSocketListener 
    { // Incoming data from the client.
    public static string data = null; public static void StartListening() 
    {
    // Data buffer for incoming data.
    byte[] bytes = new Byte[1024]; // Establish the local endpoint for the socket.
    // Dns.GetHostName returns the name of the 
    // host running the application.
    IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
    IPAddress ipAddress = ipHostInfo.AddressList[0];
    IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11100); // Create a TCP/IP socket.
    Socket listener = new Socket(AddressFamily.InterNetwork,
    SocketType.Stream, ProtocolType.Tcp ); // Bind the socket to the local endpoint and 
    // listen for incoming connections.
    try 
    {
    listener.Bind(localEndPoint);
    listener.Listen(10); // Start listening for connections.
    while (true) 
    {
    Console.WriteLine("Waiting for a connection...");
    // Program is suspended while waiting for an incoming connection.
    Socket handler = listener.Accept();
    data = null; // An incoming connection needs to be processed.
    while (true) 
    {
    bytes = new byte[1024];
    int bytesRec = handler.Receive(bytes);
    data += Encoding.UTF8.GetString(bytes,0,bytesRec);
    if (data.IndexOf("<EOF>") > -1) 
    {
    break;
    }
    } // Show the data on the console.
    Console.WriteLine( "Text received : {0}", data);
    string t="服务器端成功收到信息"; // Echo the data back to the client.
    //byte[] msg = Encoding.ASCII.GetBytes("回复:"+data); data="回复:\n"+t;
    byte[] msg = Encoding.UTF8.GetBytes(t);    
    handler.Send(msg);
    handler.Shutdown(SocketShutdown.Both);

    handler.Close();
    }
            

    catch
    {} Console.WriteLine("\nPress ENTER to continue...");
    Console.Read();
        
    }
    }
    }
      

  4.   


    以上两个类有可以实现的,但是关闭的时候,进程里还是会留有MyServer.exe的,还是有待改进
      

  5.   

    小弟在试着开发一个即时聊天的东东,现在是内网(ip:192.168.0.112)能访问到外网(61.144.60.16),也就是说能发信息到61.144.60.16这台服务器,当服务器接收到信息后,返回信息给内网时客户端的client.Receive(ref remotePoint)没有任何反应,也没有报错,具体代码码如下服务器端server:
    private void Run()
    {
    byte[] buffer = null;         byte[] msgBuffer = server.Receive(ref remotePoint);
             object msgObj = FormatterHelper.Deserialize(msgBuffer);
    Type msgType = msgObj.GetType();
    if (msgType == typeof(LoginMessage))
    {
                LoginMessage _LoginMessage=new LoginMessage();
                buffer = FormatterHelper.Serialize(_LoginMessage);
                server.Send(buffer, buffer.Length, this.remotePoint);
              }
    }
    客户端client
    public void ConnectToServer(stringfromuserid , string fromusername)
    {
    LoginMessage lginMsg = new LoginMessage();
    byte[] buffer = FormatterHelper.Serialize(lginMsg);
    client.Send(buffer, buffer.Length, hostPoint);
    buffer = client.Receive(ref remotePoint);//**********到这就没反应了

    }
    ————————————————————————————————
    首先谢谢楼上henry3695
    可能我没写清楚:以上代码
    server、client变量是udpclient类型的,我的意图是每一个客户端登陆后都会在服务上留下登陆客户端的网络地址,在这把所IpEndPoint存在Hashtable中,那么在客户登陆后,就把存在服务器端的存有IpEndPoint的Hashtable发一份到客户端,这样就为实现p2p功能作好了准备,但现是外网上的服务器不能访问内网(192.168.0.112),也就是不能把服务器中存有IpEndPoint的Hashtable下转到客端
      

  6.   

    小弟在试着开发一个即时聊天的东东,现在是内网(ip:192.168.0.112)能访问到外网(61.144.60.16),也就是说能发信息到61.144.60.16这台服务器,当服务器接收到信息后,返回信息给内网时客户端的client.Receive(ref remotePoint)没有任何反应,也没有报错,具体代码码如下服务器端server:
    private void Run()
    {
    byte[] buffer = null;         byte[] msgBuffer = server.Receive(ref remotePoint);
             object msgObj = FormatterHelper.Deserialize(msgBuffer);
    Type msgType = msgObj.GetType();
    if (msgType == typeof(LoginMessage))
    {
                LoginMessage _LoginMessage=new LoginMessage();
                buffer = FormatterHelper.Serialize(_LoginMessage);
                server.Send(buffer, buffer.Length, this.remotePoint);
              }
    }
    客户端client
    public void ConnectToServer(stringfromuserid , string fromusername)
    {
    LoginMessage lginMsg = new LoginMessage();
    byte[] buffer = FormatterHelper.Serialize(lginMsg);
    client.Send(buffer, buffer.Length, hostPoint);
    buffer = client.Receive(ref remotePoint);//**********到这就没反应了

    }
    ________________________________________
    在局域中能实现
      

  7.   

    如果是内网--内网之间通信,就是要如同 dk385(大康) 说的那样,你服务端记录下的TCP端口,在服务端客户端本次连接中止后即失效了
      

  8.   

    建议去看一下穿透内网的相关资料,应该是用UDP的 ,具体不熟,没什么可以帮得上忙的
      

  9.   

    还没结帖啊,我看了一下,P2P应该是NAT相关的穿透问题
    不过你的代码我今天看了一下,感觉问题不是出在这方面上
    你server端send时远端地址是什么呢?理论上不应该是内网地址的,而应该是你接到外网的设备上的外网地址和端口,这个在服务端(UDP)接收到信息时,同时会有客户端在外网上的地址和端口的,你的服务端要向这个地址和端口发送信息,客户端才能接收到另外,客户端这个UDP端口因为NAT设备的不同,不一定能接受不同IP(也就是不同外部)的UDP包,很有可能会过滤掉,这方面你可以搜索一下UDP打洞 相关的内容
      

  10.   

    我在服务器端把从客户端的IP端口显示出来了,看到send方的IP是我内网的代理服务器的IP,如
    是61.144.60.90,端口号会变如是1609(这本来也就这样),服务器端发送回应应是IP61.144.60.90,port1609,我的服务器代理是kingate,后来在网上查了一下,默认只支持socket4,后来调了一下,结果还是不行,我在局域中很正常,我也查过这方面的资料。。,呵呵,还是不行,现在想试试用socket构造函数 new Socket(AddressFamily.InterNetwork,
    SocketType.Stream, ProtocolType.Udp )试试,但现在办法,时间限制,先就真接用tcp了。。