写空行的聊天应用程序
Chat application writing empty lines
我用以下模型制作了一个聊天应用程序(客户端+服务器):
http://csharp.net-informations.com/communications/csharp-chat-server-programming.htm
不同之处在于,我也在控制台应用程序中制作了客户端。这是我的客户 Class:
的代码
class Program
{
static TcpClient clientSocket = new TcpClient();
static NetworkStream serverStream = default(NetworkStream);
static string readData = null;
static void Main(string[] args)
{
connect();
while (true)
{
string send = Console.ReadLine();
byte[] outStream = Encoding.ASCII.GetBytes(send + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}
}
private static void connect()
{
readData = "Connected to Chat Server...";
msg();
clientSocket.Connect("localhost", 8888);
serverStream = clientSocket.GetStream();
byte[] outStream = Encoding.ASCII.GetBytes("somerandomusername" + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
Thread ctThread = new Thread(getMessage);
ctThread.Start();
}
private static void getMessage()
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[10025];
buffSize = clientSocket.ReceiveBufferSize;
serverStream.Read(inStream, 0, buffSize);
string returndata = Encoding.ASCII.GetString(inStream);
if (returndata != null)
{
readData = "" + returndata;
msg();
}
}
}
private static void msg()
{
Console.WriteLine(">> " + readData);
}
}
这是来自我的服务器的代码 class:
class Program
{
public static Hashtable clientsList = new Hashtable();
static void Main(string[] args)
{
TcpListener serverSocket = new TcpListener(8888);
TcpClient clientSocket = default(TcpClient);
int counter = 0;
serverSocket.Start();
Console.WriteLine("Server started...");
counter = 0;
while ((true))
{
counter += 1;
clientSocket = serverSocket.AcceptTcpClient();
byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
dataFromClient = Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
clientsList.Add(dataFromClient, clientSocket);
broadcast(dataFromClient + " Joined", dataFromClient, false);
Console.WriteLine(dataFromClient + " Joined chat room");
handleClient client = new handleClient();
client.startClient(clientSocket, dataFromClient, clientsList);
}
clientSocket.Close();
serverSocket.Stop();
Console.WriteLine("exit");
Console.ReadLine();
}
public static void broadcast(string msg, string uName, bool flag)
{
foreach (DictionaryEntry client in clientsList)
{
TcpClient broadcastSocket;
broadcastSocket = (TcpClient)client.Value;
NetworkStream broadcastStream = broadcastSocket.GetStream();
Byte[] broadcastBytes = null;
if (flag == true)
{
broadcastBytes = Encoding.ASCII.GetBytes(uName + ": " + msg);
}
else
{
broadcastBytes = Encoding.ASCII.GetBytes(msg);
}
broadcastStream.Write(broadcastBytes, 0, broadcastBytes.Length);
broadcastStream.Flush();
}
}
}
public class handleClient
{
TcpClient clientSocket;
string clNo;
Hashtable clientsList;
public void startClient(TcpClient inClientSocket, string clineNo, Hashtable cList)
{
this.clientSocket = inClientSocket;
this.clNo = clineNo;
this.clientsList = cList;
Thread ctThread = new Thread(doChat);
ctThread.Start();
}
private void doChat()
{
int requestCount = 0;
byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
Byte[] sendBytes = null;
string serverResponse = null;
string rCount = null;
requestCount = 0;
while ((true))
{
try
{
requestCount = requestCount + 1;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
Console.WriteLine("From client - " + clNo + " : " + dataFromClient);
rCount = Convert.ToString(requestCount);
Program.broadcast(dataFromClient, clNo, true);
}
catch (Exception ex)
{
clientsList.Remove(clNo);
Console.WriteLine(clNo + " hat den Chat verlassen");
break;
}
}
}
}
不知为何,客户端在接收消息时显示了很多空行。这是屏幕截图:http://i.stack.imgur.com/CoF5B.png。
在第一个红色标记上方有空行。它标记了我输入消息的区域,按下回车键并写入了服务器响应。要看到它,我必须向下滚动到红色标记。然后是空行。第二个红色标记标记下一条消息将出现的区域。
如果你能帮我解决这个问题,我将不胜感激。
您确定收到短信了吗?您是否正确发送文本?你有任何错误吗?在数据广播之前设置断点,并在接收端设置断点,并检查您的变量是否包含您期望的内容。
这不是因为您正在尝试从没有任何数据的 Stream 中读取并为您提供虚拟数据导致应用程序打印没有文本的新行,因为它只是没有要发送的文本吗?
空文本的行数是否与您发送的字符串的长度相同?
我知道你的问题是这里的固定代码(在客户端):
private static void getMessage()
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
buffSize = clientSocket.Available;
byte[] inStream = new byte[buffSize];
serverStream.Read(inStream, 0, buffSize);
string returndata = Encoding.ASCII.GetString(inStream);
if (returndata != null)
{
readData = "" + returndata;
msg();
}
}
}
您将缓冲区大小读入您想要可用字节的数组。
大卫
您的问题是 Encoding.ASCII.GetString
的误用:
字节值 0 将被转换为 space,而不是您可能怀疑的 '[=12=]'
。因为你用 10025 个零初始化它,所以你有一堆 space 填满你的行。
在将 returndata
附加到 readData
之前修剪 returndata
将解决此问题,但会产生副作用,例如不允许在消息中前导和尾随 space。
你可以试试这个来理解问题:
static void Main(string[] args)
{
byte[] lolempty = new byte[1024];
string encoded = Encoding.ASCII.GetString(lolempty);
Console.WriteLine(encoded.Length.ToString());
Console.WriteLine("[{0}]", encoded);
}
我用以下模型制作了一个聊天应用程序(客户端+服务器): http://csharp.net-informations.com/communications/csharp-chat-server-programming.htm
不同之处在于,我也在控制台应用程序中制作了客户端。这是我的客户 Class:
的代码class Program
{
static TcpClient clientSocket = new TcpClient();
static NetworkStream serverStream = default(NetworkStream);
static string readData = null;
static void Main(string[] args)
{
connect();
while (true)
{
string send = Console.ReadLine();
byte[] outStream = Encoding.ASCII.GetBytes(send + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}
}
private static void connect()
{
readData = "Connected to Chat Server...";
msg();
clientSocket.Connect("localhost", 8888);
serverStream = clientSocket.GetStream();
byte[] outStream = Encoding.ASCII.GetBytes("somerandomusername" + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
Thread ctThread = new Thread(getMessage);
ctThread.Start();
}
private static void getMessage()
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[10025];
buffSize = clientSocket.ReceiveBufferSize;
serverStream.Read(inStream, 0, buffSize);
string returndata = Encoding.ASCII.GetString(inStream);
if (returndata != null)
{
readData = "" + returndata;
msg();
}
}
}
private static void msg()
{
Console.WriteLine(">> " + readData);
}
}
这是来自我的服务器的代码 class:
class Program
{
public static Hashtable clientsList = new Hashtable();
static void Main(string[] args)
{
TcpListener serverSocket = new TcpListener(8888);
TcpClient clientSocket = default(TcpClient);
int counter = 0;
serverSocket.Start();
Console.WriteLine("Server started...");
counter = 0;
while ((true))
{
counter += 1;
clientSocket = serverSocket.AcceptTcpClient();
byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
dataFromClient = Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
clientsList.Add(dataFromClient, clientSocket);
broadcast(dataFromClient + " Joined", dataFromClient, false);
Console.WriteLine(dataFromClient + " Joined chat room");
handleClient client = new handleClient();
client.startClient(clientSocket, dataFromClient, clientsList);
}
clientSocket.Close();
serverSocket.Stop();
Console.WriteLine("exit");
Console.ReadLine();
}
public static void broadcast(string msg, string uName, bool flag)
{
foreach (DictionaryEntry client in clientsList)
{
TcpClient broadcastSocket;
broadcastSocket = (TcpClient)client.Value;
NetworkStream broadcastStream = broadcastSocket.GetStream();
Byte[] broadcastBytes = null;
if (flag == true)
{
broadcastBytes = Encoding.ASCII.GetBytes(uName + ": " + msg);
}
else
{
broadcastBytes = Encoding.ASCII.GetBytes(msg);
}
broadcastStream.Write(broadcastBytes, 0, broadcastBytes.Length);
broadcastStream.Flush();
}
}
}
public class handleClient
{
TcpClient clientSocket;
string clNo;
Hashtable clientsList;
public void startClient(TcpClient inClientSocket, string clineNo, Hashtable cList)
{
this.clientSocket = inClientSocket;
this.clNo = clineNo;
this.clientsList = cList;
Thread ctThread = new Thread(doChat);
ctThread.Start();
}
private void doChat()
{
int requestCount = 0;
byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
Byte[] sendBytes = null;
string serverResponse = null;
string rCount = null;
requestCount = 0;
while ((true))
{
try
{
requestCount = requestCount + 1;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
Console.WriteLine("From client - " + clNo + " : " + dataFromClient);
rCount = Convert.ToString(requestCount);
Program.broadcast(dataFromClient, clNo, true);
}
catch (Exception ex)
{
clientsList.Remove(clNo);
Console.WriteLine(clNo + " hat den Chat verlassen");
break;
}
}
}
}
不知为何,客户端在接收消息时显示了很多空行。这是屏幕截图:http://i.stack.imgur.com/CoF5B.png。 在第一个红色标记上方有空行。它标记了我输入消息的区域,按下回车键并写入了服务器响应。要看到它,我必须向下滚动到红色标记。然后是空行。第二个红色标记标记下一条消息将出现的区域。
如果你能帮我解决这个问题,我将不胜感激。
您确定收到短信了吗?您是否正确发送文本?你有任何错误吗?在数据广播之前设置断点,并在接收端设置断点,并检查您的变量是否包含您期望的内容。
这不是因为您正在尝试从没有任何数据的 Stream 中读取并为您提供虚拟数据导致应用程序打印没有文本的新行,因为它只是没有要发送的文本吗?
空文本的行数是否与您发送的字符串的长度相同?
我知道你的问题是这里的固定代码(在客户端):
private static void getMessage()
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
buffSize = clientSocket.Available;
byte[] inStream = new byte[buffSize];
serverStream.Read(inStream, 0, buffSize);
string returndata = Encoding.ASCII.GetString(inStream);
if (returndata != null)
{
readData = "" + returndata;
msg();
}
}
}
您将缓冲区大小读入您想要可用字节的数组。
大卫
您的问题是 Encoding.ASCII.GetString
的误用:
字节值 0 将被转换为 space,而不是您可能怀疑的 '[=12=]'
。因为你用 10025 个零初始化它,所以你有一堆 space 填满你的行。
在将 returndata
附加到 readData
之前修剪 returndata
将解决此问题,但会产生副作用,例如不允许在消息中前导和尾随 space。
你可以试试这个来理解问题:
static void Main(string[] args)
{
byte[] lolempty = new byte[1024];
string encoded = Encoding.ASCII.GetString(lolempty);
Console.WriteLine(encoded.Length.ToString());
Console.WriteLine("[{0}]", encoded);
}