C#server通过NAT套接到Android Socket

时间:2014-06-19 09:01:54

标签: java c# android sockets nat

Android应用程序支持NAT(3G连接),而服务器则位于公共IP上。

Android应用程序可以连接到服务器套接字并发送数据(通过Android上的Socket / TCPclient),但由于NAT,服务器无法连接到Android端口 (服务器获取" ...未能响应" ip_adress_of_android:port_that_is_open_and_listening_on_android"。

无论如何要克服这一点,或者我可以使用一些参数来使服务器连接尝试通过NAT到达目的地而不使用自定义库? - 或者你能指点一个易于实施的方法,我没有时间学习和整合复杂的第三方图书馆

以下是我的服务器代码如何工作的示例:

int port_server, port_android;  // used to declare used ports by the server and android   
Socket server_socket, client_socket; //sockets used to receive and send data

server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                           
server_socket.Bind(new IPEndPoint(IPAddress.Any, port_server));                                                        
server_socket.Listen(0);

public void listen()
{
server_socket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}

private void AcceptCallback(IAsyncResult AR)
{
                client_socket = server_socket.EndAccept(AR);                                                                            
                buffer = new byte[client_socket.ReceiveBufferSize];                                                                     
                client_socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}

private void ReceiveCallback(IAsyncResult AR)
        {
        listen(); // to continue listening to the port
        // code that does something with the data
        send_string("Take this"); // sends a string to android
        }
public void send_string(string notif)
        {
            string ip_client = client_socket.RemoteEndPoint.ToString();                                                  
            string ip_client2 = (ip_c.Split(':'))[0];                                                               
            TcpClient client = new TcpClient(ip_client, port_android);                                             
            Byte[] notifi = System.Text.Encoding.ASCII.GetBytes(notif);                                   
            NetworkStream stream = client.GetStream();                                                              
            stream.Write(notifi, 0, notifi.Length);                                                         
            stream.Close();                                                                                         
            client.Close();                                                                                         
        }

我应该注意到它们在局域网上都是双向的,所以代码工作正常,我只需要修改它就可以通过NAT到达目标。

1 个答案:

答案 0 :(得分:1)

像这样的东西

class Program
{
    int port_server = 42424;
    Socket server_socket;

    public Program()
    {
        server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server_socket.Bind(new IPEndPoint(IPAddress.Any, port_server));
        server_socket.Listen(0);
    }

    public void Listen()
    {
        while (true)
        {
            var client = server_socket.Accept();
            var buffer = new byte[client.ReceiveBufferSize];
            client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), Tuple.Create(client, buffer));
        }
    }

    private void ReceiveCallback(IAsyncResult AR)
    {
        var state = (Tuple<Socket, byte[]>)AR.AsyncState;
        var client = state.Item1;
        var buffer = state.Item2;
        byte[] notifi = System.Text.Encoding.ASCII.GetBytes("Take this");
        client.Send(notifi);
        client.Close();
    }



    static void Main(string[] args)
    {
        var programm = new Program();
        programm.Listen();
    }
}

客户端部分

using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
    client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 42424));
    client.Send(new byte[] {1, 2, 3}, SocketFlags.None);
    byte[] bt = new byte[256];
    client.Receive(bt, 256, SocketFlags.None);
}