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 = "客户端";
    }
    到此为止,客户端程序的主要部分都已经介绍完毕。

  • 相关阅读:
    Struct2_使用Ajax调用Action方法并返回值
    Eclipse使用maven创建struct2项目及遇到的各种坑
    IIS7.5 提示未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序
    使用Canvas实现下雪功能
    基于脚本的动画的计时控制(“requestAnimationFrame”)(转)
    pointer-events属性
    chrome Provisional headers are shown错误提示
    Wcf资料收集
    Asp.Net WebApi 启用CORS跨域访问指定多个域名
    Cors 跨域Access-Control-Allow-Origin
  • 原文地址:https://www.cnblogs.com/liye/p/2208530.html
Copyright © 2011-2022 走看看