我是套接字的新手,所以我尝试创建一个服务器和一个交换消息的客户端。我在C#中创建了一个,但它给了我奇怪的错误,一旦我启动服务器它冻结并且“没有响应”消息出现...当我连接服务器时客户端也会发生同样的情况,但问题是当我关闭其中任何一个时。另一个应用程序有更新显示如此idk问题是什么,这里是使用的代码
服务器类
Socket Soc;
static ushort MaxClients = 1000;
static List<Socket> ClientList = new List<Socket>(MaxClients);
static bool ServerStarted;
public Server()
{
InitializeComponent();
button1.Enabled = false;
button2.Enabled = false;
}
private void button1_Click(object sender, EventArgs e) // Send
{
string MessageToSend = textBox1.Text;
byte[] Buffer = Encoding.Default.GetBytes(MessageToSend);
foreach (var client in ClientList)
{
Soc.Send(Buffer, 0, Buffer.Length, SocketFlags.None);
}
textBox2.Text += " Message Sent To Clients : " + MessageToSend + Environment.NewLine;
}
private void button3_Click(object sender, EventArgs e) // Start
{
StartServer("25.21.113.163", 5000);
}
private void button2_Click(object sender, EventArgs e) // Stop
{
CloseServer();
}
private void button4_Click(object sender, EventArgs e) // Exit
{
CloseServer();
Application.Exit();
}
public void StartServer(string Ip, ushort Port)
{
Soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Soc.Bind(new IPEndPoint(IPAddress.Parse(Ip), Port));
textBox2.Text += " Server Is Created On Ip : " + Ip + ", Port : " + Port + Environment.NewLine;
Soc.Listen(MaxClients);
textBox2.Text += " Server Is Listening to Clients Now... " + Environment.NewLine;
ServerStarted = true;
button1.Enabled = true;
button2.Enabled = true;
button3.Enabled = false;
label3.Text = ClientList.Count.ToString() + "/" + MaxClients;
ReceiveData();
}
public void ReceiveData()
{
while (true)
{
var Client = Soc.Accept();
ClientList.Add(Client);
label3.Text = ClientList.Count.ToString() + "/" + MaxClients;
textBox2.Text += " Client Located At Ip : " + Client.RemoteEndPoint.ToString().Split(':')[0].ToString() + " Is Now Connected To Server " + Environment.NewLine;
while (true)
{
byte[] ReceivedBytes = new byte[1024];
int ReceivedDataLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
string MessageFromClient = Encoding.Default.GetString(ReceivedBytes, 0, ReceivedDataLength);
textBox2.Text += " Message Sent to Server : " + MessageFromClient + Environment.NewLine;
}
}
}
public void CloseServer()
{
Soc.Close();
ServerStarted = false;
textBox2.Text += " Server Is Closed Now... " + Environment.NewLine;
button3.Enabled = true;
button2.Enabled = false;
button1.Enabled = false;
}
客户端类
Socket Client;
public Form1()
{
InitializeComponent();
button1.Enabled = false;
button2.Enabled = false;
}
private void button1_Click(object sender, EventArgs e) // Send
{
string MessageToSend = textBox2.Text;
byte[] Buffer = Encoding.Default.GetBytes(MessageToSend);
Client.Send(Buffer, 0, Buffer.Length, SocketFlags.None);
textBox1.Text += " Sent Message To Server Is : " + MessageToSend + Environment.NewLine;
}
private void button2_Click(object sender, EventArgs e) // LogOut
{
ClientClose();
}
private void button3_Click(object sender, EventArgs e) // Connect
{
ConnectToServer("25.21.113.163", 5000);
}
private void button4_Click(object sender, EventArgs e) // Exit
{
ClientClose();
Application.Exit();
}
public void ConnectToServer(string Ip, ushort Port)
{
try
{
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Client.Connect(Ip, Port);
textBox1.Text += " You Are Now Connected To Server Hosted On Ip : " + Client.RemoteEndPoint + Environment.NewLine;
button1.Enabled = true;
button2.Enabled = true;
button3.Enabled = false;
ReceiveData();
}
catch
{
textBox1.Text += " Server In Offline Now " + Environment.NewLine;
}
}
public void ReceiveData()
{
while (true)
{
byte[] ReceivedBytes = new byte[1024];
int ReceivedBytesLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
string ReceivedMessage = Encoding.Default.GetString(ReceivedBytes, 0, ReceivedBytesLength);
textBox1.Text += " Received Message From Server Is : " + ReceivedMessage + Environment.NewLine;
}
}
public void ClientClose()
{
button1.Enabled = false;
button2.Enabled = false;
button3.Enabled = true;
Client.Dispose();
Client.Close();
textBox1.Text += " You Are Disconnected From Server" + Environment.NewLine;
}
我想知道我做错了什么?我怎样才能摆脱这两种应用程序的“无响应”状态?
答案 0 :(得分:0)
首先,让我们对您的代码进行更正以使其正常工作,谢谢我提供一些Asynchronous Socket
教程,这比Synchronous
容易得多。
你的问题在这一行:
public void ReceiveData()
{
while (true)
{
var Client = Soc.Accept();
ClientList.Add(Client);
label3.Text = ClientList.Count.ToString() + "/" + MaxClients;
textBox2.Text += " Client Located At Ip : " + Client.RemoteEndPoint.ToString().Split(':')[0].ToString() + " Is Now Connected To Server " + Environment.NewLine;
while (true)
{
byte[] ReceivedBytes = new byte[1024];
int ReceivedDataLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
string MessageFromClient = Encoding.Default.GetString(ReceivedBytes, 0, ReceivedDataLength);
textBox2.Text += " Message Sent to Server : " + MessageFromClient + Environment.NewLine;
}
}
}
这是因为两个原因:
1)您必须侦听到单独线程的传入连接。
2)您必须在单独的线程中监听每个客户端,因此它们不会相互阻塞。在您的示例中,正在侦听客户端的第二个while(true)
阻止服务器套接字接受其他客户端。将其重构为:
public void ReceiveData()
{
new Thread(() =>
{
while (true)
{
var Client = Soc.Accept();
ClientList.Add(Client);
label3.Text = ClientList.Count.ToString() + "/" + MaxClients;
textBox2.Text += " Client Located At Ip : " + Client.RemoteEndPoint.ToString().Split(':')[0].ToString() + " Is Now Connected To Server " + Environment.NewLine;
new Thread(() =>
{
while (true)
{
byte[] ReceivedBytes = new byte[1024];
int ReceivedDataLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
string MessageFromClient = Encoding.Default.GetString(ReceivedBytes, 0, ReceivedDataLength);
textBox2.Text += " Message Sent to Server : " + MessageFromClient + Environment.NewLine;
}
}).Start();
}
}).Start();
}
此方法为每个客户端使用单独的线程来处理来自客户端的接收数据。
我还为客户端应用添加了代码:
public void ReceiveData()
{
new Thread(() =>
{
while (true)
{
byte[] ReceivedBytes = new byte[1024];
int ReceivedBytesLength = Client.Receive(ReceivedBytes, 0, ReceivedBytes.Length, SocketFlags.None);
string ReceivedMessage = Encoding.Default.GetString(ReceivedBytes, 0, ReceivedBytesLength);
textBox1.Text += " Received Message From Server Is : " + ReceivedMessage + Environment.NewLine;
}
}).Start();
}
将来看看Asynchronous Sockets
,您将不再需要处理多线程问题。
http://msdn.microsoft.com/en-us/library/fx6588te.aspx
http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx
编辑更新了客户/服务