zoukankan      html  css  js  c++  java
  • C#中的套接字编程(二) 转

    客户端程序的代码编写:
        布置界面。往界面上添加一个ListBox控件(用于显示用户列表),一个RichTextBox控件(用于显示聊天消息以及系统消息),一个 TextBox控件(用于发送消息),一个CheckBox控件(确定是否为悄悄话),一个StatusBar控件(name=StatusBar1)以 及四个Button控件(分别为“连接”、“断开连接”、“开始记录”、“发送”)。
        当客户端试图和服务器端进行连接时,一个连接必须建立而且得向服务器端进行注册。 ConnectionServer()函数运用一个TcpClient来和服务器端取得连接,同时创建一个NetworkStream来发送消息。还有, 端口号和服务器端的是保持一致的。
    先声明如下变量:
    private System.Net.Sockets.TcpClient clientSocket;
    private System.Net.Sockets.NetworkStream ns;
    private System.IO.StreamReader sr;
    ConnectionServer()函数如下:
    private void ConnectionServer()
    {
        StatusBar1.Text = "正在连接到服务器……";
        try
        {
            clientSocket = new System.Net.Sockets.TcpClient(serverAddress,serverPort);
            ns = clientSocket.GetStream();
            sr = new System.IO.StreamReader(ns);
            connected = true;
        }
        catch (Exception)
        {
            MessageBox.Show("不能连接到服务器!","错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            StatusBar1.Text = "已断开连接";
        }
    }
        在和服务器端连接成功后,程序就用RegisterWithServer()函数向服务器端发送一个CONN命令。该命令先是发送该用户的名称,然后从服务器端获得其他所有用户的列表,所有用户列表是在ListBox控件中显示的。
    RegisterWithServer()函数如下:
    private void RegisterWithServer()
    {
        try
        {
            string command = "CONN|" + ChatOut.Text;
            Byte[] outBytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
            ns.Write(outBytes,0,outBytes.Length);
            string serverResponse = sr.ReadLine();
            serverResponse.Trim();
            string[] tokens = serverResponse.Split(new Char[]{'|'});
            if(tokens[0] == "LIST")
            {
                StatusBar1.Text = "已连接";
                btnCloseConnection.Enabled = true;
            }
            for(int n=1; n<tokens.Length;n++)
                lbChatters.Items.Add(tokens[n].Trim(new char[]{'\r','\n'}));
            this.Text = clientName + ":已连接到服务器";
        }
        catch (Exception)
        {
            MessageBox.Show("注册时发生错误!","错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
    }
        在此之后,当然就是用户之间的聊天了,由ReceiveChat()函数来完成。该函数是一个独立的线程,它处理所有用户获得的消息和用户发送的消息。它主要处理了CHAT、PRIV、JOIN、GONE、QUIT等命令,处理的方法和服务器端的类似。
    ReceiveChat()函数实现如下:
    private void ReceiveChat()
    {
        bool keepAlive = true;
        while (keepAlive)
        {
            try
            {
                Byte[] buffer = new Byte[2048];
                ns.Read(buffer,0,buffer.Length);
                string chatter = System.Text.Encoding.ASCII.GetString(buffer);
                string[] tokens = chatter.Split(new Char[]{'|'});
                if (tokens[0] == "CHAT")
                {
                    rtbChatIn.AppendText(tokens[1]);
                    if(logging)
                        logwriter.WriteLine(tokens[1]);
                }
                if (tokens[0] == "PRIV")
                {
                    rtbChatIn.AppendText("Private from ");
                    rtbChatIn.AppendText(tokens[1].Trim() );
                    rtbChatIn.AppendText(tokens[2] + "\r\n");
                    if(logging)
                    {
                        logwriter.Write("Private from ");
                        logwriter.Write(tokens[1].Trim() );
                        logwriter.WriteLine(tokens[2] + "\r\n");
                    }
                }
                if (tokens[0] == "JOIN")
                {
                    rtbChatIn.AppendText(tokens[1].Trim() );
                    rtbChatIn.AppendText(" has joined the Chat\r\n");
                    if(logging)
                    {
                        logwriter.WriteLine(tokens[1]+" has joined the Chat");
                    }
                    string newguy = tokens[1].Trim(new char[]{'\r','\n'});
                    lbChatters.Items.Add(newguy);
                }
                if (tokens[0] == "GONE")
                {
                    rtbChatIn.AppendText(tokens[1].Trim() );
                    rtbChatIn.AppendText(" has left the Chat\r\n");
                    if(logging)
                    {
                        logwriter.WriteLine(tokens[1]+" has left the Chat");
                    }
                    lbChatters.Items.Remove(tokens[1].Trim(new char[]{'\r','\n'}));
                }
                if (tokens[0] == "QUIT")
                {
                    ns.Close();
                    clientSocket.Close();
                    keepAlive = false;
                    StatusBar1.Text = "服务器端已停止";
                    connected= false;
                    btnSend.Enabled = false;
                    btnCloseConnection.Enabled = false;
                }
            }
            catch(Exception){}
        }
    }
        通过以上的一些函数,客户端程序之间就可以进行自由地聊天了,各个用户之间还可以互相发送悄悄话。所以程序已经实现了聊天室的基本功能了,不过最后各个用户还要正常地退出,那就要用到QuitChat()函数了。
    QuitChat()函数的具体实现如下:
    private void QuitChat()
    {
        if(connected)
        {
            try
            {
                string command = "GONE|" + clientName;
                Byte[] outBytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
                ns.Write(outbytes,0,outbytes.Length);
                clientSocket.Close();
            }
            catch(Exception)
            {
            }
        }
        if(logging)
            logwriter.Close();
        if(receive != null && receive.IsAlive)
            receive.Abort();
        this.Text = "客户端";
    }
    到此为止,客户端程序的主要部分都已经介绍完毕。

  • 相关阅读:
    poj 1743 Musical Theme 后缀数组
    poj 1743 Musical Theme 后缀数组
    cf 432D Prefixes and Suffixes kmp
    cf 432D Prefixes and Suffixes kmp
    hdu Data Structure? 线段树
    关于position和anchorPoint之间的关系
    ios POST 信息
    CALayers的代码示例
    CALayers详解
    ios中得sqlite使用基础
  • 原文地址:https://www.cnblogs.com/liye/p/2208530.html
Copyright © 2011-2022 走看看