聊天应用程序写空行

时间:2015-07-31 14:44:57

标签: c# client server chat

我用以下模型制作了一个聊天应用程序(客户端+服务器): http://csharp.net-informations.com/communications/csharp-chat-server-programming.htm

不同之处在于,我也在控制台应用程序中创建了客户端。这是我的客户类的代码:

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);
    }
}

这是我的Server类的代码:

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。 在第一个红色标记上方有空行。它标记了我输入消息的区域,按下回车键并写入了服务器响应。看到它我将不得不向下滚动到红色标记。然后有空行。第二个红色标记表示下一条消息出现的区域。

如果你能帮我解决这个问题,我真的很感激。

3 个答案:

答案 0 :(得分:1)

您确定收到任何文字吗?你正确发送文字了吗?你有任何错误吗?在广播数据之前设置断点,并在接收端设置断点,并检查您的变量是否包含您希望它们包含的内容。

是不是你试图从没有任何数据的Stream读取并给你dummydata导致应用程序打印没有文本的新行的原因是什么因为它没有要发送的文本?

空文本的行数是否与您发送的字符串的长度相同?

答案 1 :(得分:1)

我看到你的问题是固定代码(在客户端):

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();
        }
    }
}

您可以将缓冲区大小读入需要可用字节的数组。

大卫

答案 2 :(得分:0)

您的问题是误导Encoding.ASCII.GetString: 字节值0将转换为空格,而不是您可能怀疑的'\0'。而且,由于你用10025零初始化它,你会有一堆空间填满你的线。 在将returndata附加到readData之前修剪它将解决此问题,但会产生副作用,例如不允许在邮件中使用前导和尾随空格。

您可以尝试这样来理解问题:

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);
}