You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中不使用TcpListener获取TCP客户端IP和端口

解决TCP Socket获取客户端IP和端口的问题

Hey there! Let's fix your issue with getting the TCP client's IP and port using raw Sockets in C#—no TcpListener needed, and we’ll make sure we grab that info before the if(rc>0) check in your getmsg method.

核心问题分析

There are a couple of key issues in your current code that are blocking you:

  • TCP is connection-oriented: The socketClient you get from socketServer.Accept() is already a connected socket—it holds all the remote client's endpoint info natively. You don’t need ReceiveFrom (that’s for UDP, a connectionless protocol) to get this data.
  • Hardcoded iprec is breaking things: You manually set iprec to 127.0.0.1:4040, which overwrites the actual client details. That’s why you can’t get the real IP/port.
  • Timing mismatch: We need to capture the client info early—either right after accepting the connection, or at the very start of the getmsg method, before checking rc>0.

修改后的代码示例

Here’s a revised version of your code that fixes all these issues:

  • We grab the client’s IP/port immediately after accepting the connection
  • Pass this info (and the client socket) to the getmsg thread using ParameterizedThreadStart
  • Replace ReceiveFrom with Receive (appropriate for TCP)
  • Ensure client info is available before the rc>0 check
namespace Example
{
    public partial class TCP_Server : Form
    {
        Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        public TCP_Server()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
        }

        private void Form1_Load(object sender, EventArgs e) { }

        public void start()
        {
            IPEndPoint ipens = new IPEndPoint(IPAddress.Parse(txt_ip.Text), int.Parse(txt_port.Text));
            socketServer.Bind(ipens);
            MessageBox.Show("Waiting for clients...");
            
            while (true)
            {
                socketServer.Listen(2);
                Socket socketClient = socketServer.Accept();
                
                // Get client IP and port RIGHT AFTER accepting the connection
                IPEndPoint clientEndPoint = (IPEndPoint)socketClient.RemoteEndPoint;
                string clientInfo = $"IP: {clientEndPoint.Address}, Port: {clientEndPoint.Port}";
                MessageBox.Show($"Accepted connection from {clientInfo}");

                // Pass both the client socket and its info to the thread
                Thread trgetmsg = new Thread(new ParameterizedThreadStart(getmsg));
                trgetmsg.Start(new object[] { socketClient, clientInfo });
            }
        }

        public void getmsg(object state)
        {
            // Unpack the thread parameters
            object[] args = (object[])state;
            Socket socketClient = (Socket)args[0];
            string clientInfo = (string)args[1];

            int counter = 0;
            string[] barray2 = new string[10];
            
            try
            {
                while (true)
                {
                    byte[] barray = new byte[1024];
                    int rc = socketClient.Receive(barray);
                    
                    // 👉 Client info is already available here, BEFORE the rc>0 check
                    MessageBox.Show(clientInfo);

                    barray2[counter] = Encoding.Unicode.GetString(barray, 0, rc);
                    counter++;

                    if (rc > 0)
                    {
                        // Added a check for counter >1 to avoid index out of bounds
                        if (counter > 1 && barray2[0] == barray2[1])
                        {
                            listBox1.Items.Add($"Client ({clientInfo}): {Encoding.Unicode.GetString(barray, 0, rc)}");
                            socketClient.Send(Encoding.Unicode.GetBytes(barray2[0]));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // Don't swallow exceptions—log them for debugging
                MessageBox.Show($"Connection error: {ex.Message}");
                socketClient.Close();
            }
        }
    }
}

关键说明

  • No global socketClient: If multiple clients connect, a global variable would get overwritten, causing old threads to handle the wrong connection. Each thread now holds its own client socket instance.
  • RemoteEndPoint usage: The socketClient.RemoteEndPoint property returns an EndPoint—cast it to IPEndPoint to access the Address and Port properties.
  • Thread parameter passing: ParameterizedThreadStart lets us send multiple values to the thread method, so we can pass both the client socket and pre-fetched info.

This setup ensures you get the client’s IP and port before the if(rc>0) check, uses only raw Sockets, and fixes the connection handling issues in your original code.

内容的提问来源于stack exchange,提问作者Alireza.Doustmohammadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:01:36