c#服务器套接字到Android套接字的NAT

本文关键字:套接字 NAT Android 服务器 | 更新日期: 2023-09-27 18:09:12

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

Android应用程序可以连接到服务器套接字并发送数据(通过Android上的socket/TCPclient),但由于nat,服务器无法连接到Android端口(服务器收到"…响应" ip_address_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();                                                                                         
        }

我应该注意的是,他们的工作方式,当在一个局域网,所以代码是工作的,我只需要修改是,使它可以达到android目标通过nat。

c#服务器套接字到Android套接字的NAT

像这样

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);
}