我在C#中制作TCP服务器,我有以下几个代码:
TCP服务器:
private void startButton_Click(object sender, EventArgs e)
{
Server.Bind(Self);
Server.Listen(10);
Accept = new Thread(HandleClients);
Receive = new Thread(HandleMessages);
Accept.Start();
Receive.Start();
}
void HandleClients()
{
while (true)
{
AllUsers.Add(new Participant(Server.Accept()));
}
}
void HandleMessages()
{
while (true)
{
int Count = AllUsers.Count;
for (int i = 0; i < Count; i++)
{
if (AllUsers[i].Socket.Available > 0)
{
byte[] Data = new byte[1500];
AllUsers[i].Socket.Receive(Data); // i == 0 right here
Thread handle = new Thread(() => HandleInput(Data, AllUsers[i])); // all of the sudden i==1 right here
handle.Start();
}
Thread.Sleep(1);
}
Thread.Sleep(1);
}
}
TCP客户端:
private void connectButton_Click(object sender, EventArgs e)
{
Client.Connect(Server);
Send("0x01" + "!" + usernameText.Text); // Send username
ReceiveThread = new Thread(Receive);
ReceiveThread.Start();
}
如您所见,服务器代码旨在接受和处理多个TCP连接,而不使用异步I / O(我使用Socket.Available属性来检查数据)。
所以当有人连接时,服务器有时会崩溃。当用户连接时,他在连接后立即发送他的用户名,这导致服务器打开一个新线程来处理用户的数据包。
有时候,当有人连接并发送他的用户名(连接后立即发送用户名)时,服务器会在FOR循环内的IF区域崩溃。崩溃发生在使用lambda表达式创建新线程的部分 - 不知何故,有时FOR循环(i)的迭代器没有明显的原因增加1,这会导致抛出ArgumentOutOfRangeException。
例如,在任何人连接之前,列表的计数为0.当有人连接时,他会立即被添加到用户列表中,将其计数从0增加到1.现在,FOR循环最终开始工作在他连接之后,但有时会发生奇怪的事情。在接收行,变量i等于0,该行接收字节数组并将其放入Data变量。在下一行中,创建一个新线程,并将当前用户对象(AllUsers [i])作为参数传递给它。但有些奇怪的是,有时当参数传递时,变量i会以某种方式等于1,结果抛出异常。
有谁知道为什么会这样?我认为多线程出错了,但我不确定是什么。
谢谢,
-BlueRay101 -