我正在使用C#Windows Froms编写聊天应用程序。我的问题是,我的服务器可以向每个连接的客户端发送消息,但是只有发送消息的客户端才能收到响应。我试图创建一个带有无限循环的ReceiveLoop()之类的函数,或者添加一个计时器并为每个刻度调用Receive()函数,但是由于应用程序崩溃,两者均未成功。 如何实时获取数据?我附上了客户的应用代码。
public partial class Form1 : Form
{
private string name;
private Socket _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private void Namebt_Click(object sender, EventArgs e)
{
if (!Test(Nametb.Text)) Nametb.Text = "Nie wpisano nazwy!";
else
{
name = Nametb.Text;
Nametb.Clear();
Nametb.Enabled = false;
Namebt.Enabled = false;
Messageslb.Enabled = true;
timer1.Start();
LoopConnect();
}
}
private void LoopConnect()
{
int attempts = 0;
while (!_clientSocket.Connected)
{
try
{
attempts++;
_clientSocket.Connect(IPAddress.Loopback, 100);
}
catch (SocketException)
{
Messageslb.Items.Clear();
Messageslb.Items.Add("Connection attempts: " + attempts.ToString());
Messageslb.Refresh();
}
}
Messageslb.Items.Add("Connected!");
Messageslb.Refresh();
Messagetb.Enabled = true;
Sendbt.Enabled = true;
}
private bool Test(string text)
{
if (text != "") return true;
return false;
}
private void Sendbt_Click(object sender, EventArgs e)
{
if (!Test(Messagetb.Text)) Messagetb.Text = "Nie wpisano zadnej wiadomosci!";
else
{
Send();
}
}
private void Receive()
{
if(_clientSocket.ReceiveBufferSize > 0)
{
byte[] receivedBuffer = new byte[1024];
int rec = _clientSocket.Receive(receivedBuffer);
byte[] data = new byte[rec];
Array.Copy(receivedBuffer, data, rec);
Messageslb.Items.Add(Encoding.ASCII.GetString(data));
}
}
private void Send()
{
string message = "[" + name + "]: " + Messagetb.Text;
Messagetb.Clear();
byte[] buffer = Encoding.ASCII.GetBytes(message);
_clientSocket.Send(buffer);
Receive();
}
private void Nametb_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return) Namebt_Click(sender, e);
}
private void Messagetb_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return) Sendbt_Click(sender, e);
}
private void timer1_Tick(object sender, EventArgs e)
{
Receive();
}
}
答案 0 :(得分:0)
您需要在单独的任务上运行receive方法。
_clientSocket.Receive(receivedBuffer);
应为:
private Task _receiving;
private void Receive()
{
if(_clientSocket.ReceiveBufferSize > 0)
{
if(_receiving == null || _receiving.IsCompleted)
_receiving = Task.Run(() =>
{
byte[] receivedBuffer = new byte[1024];
int rec = _clientSocket.Receive(receivedBuffer);
byte[] data = new byte[rec];
Array.Copy(receivedBuffer, data, rec);
Messageslb.Items.Add(Encoding.ASCII.GetString(data));
});
}
}
否则,clientSocket.Receive将挂起您的程序。
您将要确保Messageslb是线程安全的,这需要进一步研究。
如果您要进行实时通信,请查看C#https://msdn.microsoft.com/en-us/library/ms946701.aspx的RTC Client。否则,我强烈推荐Socket.IO,因为它使用起来非常简单,并且可以通过非常快速的rtc进行设置! https://socket.io/get-started/chat