如何在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
socketClientyou get fromsocketServer.Accept()is already a connected socket—it holds all the remote client's endpoint info natively. You don’t needReceiveFrom(that’s for UDP, a connectionless protocol) to get this data. - Hardcoded
iprecis breaking things: You manually setiprecto127.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
getmsgmethod, before checkingrc>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
getmsgthread usingParameterizedThreadStart - Replace
ReceiveFromwithReceive(appropriate for TCP) - Ensure client info is available before the
rc>0check
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. RemoteEndPointusage: ThesocketClient.RemoteEndPointproperty returns anEndPoint—cast it toIPEndPointto access theAddressandPortproperties.- Thread parameter passing:
ParameterizedThreadStartlets 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
相关产品推荐
相关产品推荐

