【发布时间】:2014-11-26 18:58:43
【问题描述】:
所以我正在使用 C# 创建一个基于套接字的网络聊天。这是一个学校项目。 这是基本的服务器-客户端聊天 -> 客户端向服务器发送消息,服务器“广播” == 向所有连接的客户端发送消息。
但是,如果我连接两个客户端,并从一个客户端向另一个客户端发送消息,我只会得到类似的结果:
▯▯▯▯▯▯▯▯▯▯
当我再次按“发送”(显示相同的消息)时,结果很好。
这是接收函数。我在线程中使用它。
public void wait()
{
byte[] bytes = new byte[1024];
while (!shutdown)
{
// if (shutdown) break;
try
{
int bytesRec = senderSocket.Receive(bytes);
Dispatcher.Invoke(new Action(() =>
{
output.Text += "\n" + Encoding.UTF8.GetString(bytes, 0, bytesRec);
if (scroll.VerticalOffset == scroll.ScrollableHeight)
{
scroll.ScrollToEnd();
}
}));
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
}
这是用于发送的:(LCP是我自己的“协议”..忽略这个,它只是在字符串中添加一个字母)
private void send_Click(object sender, RoutedEventArgs e)
{
try
{
LCP protocol = new LCP();
string messg = user.Text + " pravi: " + message.Text ;
string messag = protocol.CreateMessage(messg, "M");
byte[] msg = Encoding.UTF8.GetBytes(messag);
// Send the data through the socket.
senderSocket.Send(msg);
// int bytesRec = senderSocket.Receive(bytes);
//output.Text += "\n" + Encoding.UTF8.GetString(bytes, 0, bytesRec);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
这就是我在服务器上处理事情的方式:
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
while (true)
{
Socket handler = listener.Accept();
data = null;
users.Add(handler.RemoteEndPoint);
socks.Add(handler);
new Thread(new ThreadStart(() =>
{
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data = Encoding.UTF8.GetString(bytes, 0, bytesRec);
LCP protocolParser = new LCP();
Dictionary<string, string> wholeMessage = protocolParser.ParseMessage(data);
if (wholeMessage["type"] == "$J")
{
Console.WriteLine("\nPridružil se je " + wholeMessage["message"]);
byte[] msg = Encoding.UTF8.GetBytes(wholeMessage["message"] + " se je pridružil");
foreach (Socket edp in socks)
{
edp.Send(msg);
//handler.SendTo(msg,edp);
}
}
// Show the data on the console.
else if (wholeMessage["type"] == "$Q")
{
handler.Shutdown(SocketShutdown.Receive);
handler.Close();
socks.Remove(handler);
break;
}
else
{
Console.WriteLine("\n" + wholeMessage["message"]);
byte[] msg = Encoding.UTF8.GetBytes(wholeMessage["message"]);
// Dispatcher.Invoke(new Action(() =>
//{
foreach (Socket edp in socks)
{
edp.Send(msg);
//handler.SendTo(msg,edp);
}
// }));
}
}
//tvoja koda
})
){IsBackground=true}.Start();
// An incoming connection needs to be processed.
// Echo the data back to the client.
}
}
【问题讨论】:
-
感谢您提供您的代码以及实际出了什么问题。鉴于大量的代码,您是否能够缩小问题范围?
-
你从哪里得到
▯▯▯▯▯▯▯▯▯▯,它是在客户端往返之后还是在服务器上的Console.WriteLine("\n" + wholeMessage["message"]);? -
服务器写一个空行...所以我也在服务器上猜,-> 因为服务器是控制台,我猜控制台不能写矩形
-
最明显的问题是您没有任何机制来确保您已读取所有发送的数据,这可能导致您的 UTF8 解码不同步(可能如果用户名或消息本身包含非 ASCII 字符,则会发生这种情况)。这会导致您似乎遇到的解码错误。另一个问题是您似乎没有正确处理套接字关闭,但这是一个单独的问题;即不会导致文本错误。