c# - 为什么我的 C# Socket 服务器不允许客户端的多个实例仅从本地计算机连接?
问题描述
我以前曾让此代码正常工作,但不确定我目前遇到的问题的原因。我正在为加密聊天编写一个简单的客户端/服务器应用程序。服务器允许多个同时客户端。当我将服务器绑定到本地IP地址时,我可以同时连接多个本地客户端,但是当我将它绑定到外部IP地址时,只有本地机器上的第一个实例会连接,但其他设备可能会同时连接多个实例. 在这种情况下,即使关闭第一个实例也不会允许另一个实例连接,并且永远不会调用 AcceptCallBack。我无法找到有关此问题的任何其他报告。想到的原因包括我在代码中犯了某种错误,或者我需要分别监听本地连接和远程连接,
对于我的服务器,我有:
public partial class frmServer : Form
{
Thread listenThread;
private static bool listening = false;
private static List<StateObject> Users = new List<StateObject>();
public frmServer()
{
InitializeComponent();
}
private void frmServer_Load(object sender, EventArgs e)
{
listenThread = new Thread(new ThreadStart(StartListening));
listenThread.Start();
}
public static void StartListening()
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 19541);
// 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(100);
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
listening = true;
while (true)
{
//check if there are new connections
if (!listening)
{
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
listening = true;
}
Thread.Sleep(50);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static void AcceptCallback(IAsyncResult ar)
{
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
listening = false;
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
Users.Add(state);
}
}
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
//user info
}
而对于我的客户
public partial class frmClient : Form
{
public frmClient()
{
InitializeComponent();
}
private void frmClient_Load(object sender, EventArgs e)
{
StartClient();
}
private void StartClient()
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
IPHostEntry ipHostInfo = Dns.GetHostEntry("Remote Host Address");
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP V4 socket.
Socket client = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
// Signal that the connection has been made.
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
解决方案
推荐阅读
- javascript - 无法从 rails 中的 vendor 文件夹加载资产
- javascript - HUGO:由于 MIME 类型(“text/html”)不匹配而被阻止(X-Content-Type-Options: nosniff)
- ios - 从 Swift 中的 Share Extension 获取数据
- r - 将新值添加到 R 中的嵌套列表中
- excel - 更改为动态 vba
- c# - C# - 如何使用需要泛型类型的泛型类型创建实例?
- r - R中的(业余)数据操作:变量级别作为新列,其值来自另一列
- javascript - 当我删除 index.css 时,Create-react-app 中断
- swift - CMTime在编码和解码媒体之外有任何实际应用吗
- sql - 修改分区表