C# Socket多线程编程(二)

//实现客户端代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ChartClient
{
    public partial class ClientMain : Form
    {
        public ClientMain()
        {
            InitializeComponent();
        }
        //NetworkStream
        System.Net.Sockets.NetworkStream ns;
        //数据量
        System.IO.StreamReader sr;
        //客户端连接
        System.Net.Sockets.TcpClient clientsocket;
        //是否连接
        bool connected;
        //接收信息线程
        System.Threading.Thread receive;
        //服务器网络地址
        string serveraddress = "192.168.104.110";
        //服务器端口号
        int serverport = 6666;
        //客户端连接名称
        string clientname;
        //操纵其他线程
        System.Threading.Thread t;
        //实现操纵其他线程委托
        public delegate void MyInvoke(string c);

        private void btnConnect_Click(object sender, EventArgs e)
        {
            //连接服务器
            EstablishConnection();
            //注册
            RegisterWithServer();
            //连接成功
            if (connected)
            {
                //接受信息线程
                receive = new System.Threading.Thread(new System.Threading.ThreadStart(ReceiveChat));
                //启动线程
                receive.Start();
            }
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            //退出
            QuitChat();
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            //连接成功
            if (connected)
            {
                try
                {
                    //创建信息
                    string command = "CHAT|" + clientname + ":" + ChatOut.Text + "/r/n";
                    //转化为字节流
                    Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
                    //发送信息
                    ns.Write(outbytes, 0, outbytes.Length);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("发生错误:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
        }
        /// <summary>
        /// 连接服务器
        /// </summary>
        private void EstablishConnection()
        {
            //更改提示栏状态
            statusBar1.Text = "正在连接到服务器";

            try
            {
                //根据网络地址和端口号获取服务器端连接
                clientsocket = new System.Net.Sockets.TcpClient(serveraddress, serverport);
                //获取发送和接受数据的NetWorkStream
                ns = clientsocket.GetStream();
                //为NetWorkStream 初始化StreamReader实例
                sr = new System.IO.StreamReader(ns);
                //设置为已连接
                connected = true;
            }
            catch (Exception e)
            {
                //提示信息
                MessageBox.Show("不能连接到服务器!发生错误:" + e.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                //设置提示信息
                statusBar1.Text = "已断开连接";
            }
        }
        /// <summary>
        /// 注册到服务器
        /// </summary>
        private void RegisterWithServer()
        {
            //清空信息
            lbChatters.Items.Clear();
            //获取客户端名称
            clientname = clientName.Text;
            try
            {
                //消息内容
                string command = "CONN|" + clientName.Text;
                //将消息字符串转换为字节
                Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
                //写入NetWorkStream中
                ns.Write(outbytes, 0, outbytes.Length);
                //获取返回的信息
                string serverresponse = sr.ReadLine();
                //移除信息两端的空白字符
                serverresponse.Trim();
                //使用“|”分隔消息
                string[] tokens = serverresponse.Split('|');
                //LIST:返回所有连接到服务器的客户端连接。发送格式:LIST|客户端名称|客户端名称|...
                if (tokens[0] == "LIST")
                {
                    //更改提示状态
                    this.statusBar1.Text = "已连接";
                    //启用断开连接按钮
                    btnDisconnect.Enabled = true;
                    //启用发送信息按钮
                    btnSend.Enabled = true;
                }
                //加入有已经连接到服务器的连接
                if (tokens[1] != "")
                {
                    //遍历消息数组
                    for (int n = 1; n < tokens.Length - 1; n++)
                    {
                        //将信息逐条添加到列表中
                        lbChatters.Items.Add(tokens[n].Trim(new char[] { '/r', '/n', '/0' }));
                    }
                    //窗口标题
                    this.Text = clientname + ":已连接到服务器";
                }
            }
            catch (Exception e)
            {
                //提示错误信息
                MessageBox.Show("注册时发生错误:" + e.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                //断开连接
                connected = false;
            }
        }
        /// <summary>
        /// 接收消息
        /// </summary>
        private void ReceiveChat()
        {
            //保持连接状态
            bool keepalive = true;
            //循环
            while (keepalive)
            {
                try
                {
                    //创建字节流
                    Byte[] buffer = new Byte[1024];
                    //获取收到的消息
                    ns.Read(buffer, 0, buffer.Length);
                    //将字节流转化为字符串
                    string chatter = System.Text.Encoding.ASCII.GetString(buffer);
                    //分隔消息数组
                    string[] tokens = chatter.Split('|');
                    //CHAT:是否为群发消息
                    if (tokens[0] == "CHAT")
                    {
                        //在消息面板上显示消息
                        t = new System.Threading.Thread(delegate()
                        {
                            setInfo(tokens[1].Trim(new char[] { '/r', '/n', '/0' }));
                        });
                        t.Start();
                    }
                    //PRIV:是否为私聊消息
                    if (tokens[0] == "PRIV")
                    {
                        //在消息面板上显示:信息Private form(来自)
                        t = new System.Threading.Thread(delegate()
                        {
                            setInfo("Private from " + tokens[1] + tokens[2].Trim(new char[] { '/r', '/n', '/0' }) + "/r/n");
                        });
                        t.Start();
                    }
                    //JOIN:是否添加新连接消息
                    if (tokens[0] == "JOIN")
                    {
                        //在消息面板上显示消息
                        t = new System.Threading.Thread(delegate()
                        {
                            setInfo(tokens[1].Trim(new char[] { '/r', '/n', '/0' }) + " has joined the Chat/r/n");
                            setChatter(tokens[1].Trim(new char[] { '/r', '/n', '/0' }), "add");
                        });
                        t.Start();
                    }
                    //GONE:是否为退出消息
                    if (tokens[0] == "GONE")
                    {
                        //在消息面板上显示退出消息
                        t = new System.Threading.Thread(delegate() 
                            {
                                setInfo(tokens[1].Trim(new char[] { '/r', '/n', '/0' }) + " has left the Chat/r/n");
                                setChatter(tokens[1].Trim(new char[] { '/r', '/n', '/0' }), "del");
                            });
                        t.Start();
                    }
                    //QUIT:此客户端退出
                    if (tokens[0] == "QUIT")
                    {
                        //关闭NetWorkStream
                        ns.Close();
                        //关闭客户端连接
                        clientsocket.Close();
                        //停止接收消息
                        keepalive = false;
                        //提示消息线程
                        t = new System.Threading.Thread(delegate() { setState("服务器端已停止"); });
                        //启动线程
                        t.Start();
                        //断开连接
                        connected = false;
                    }
                }
                catch (Exception e)
                {
                    //提示异常信息
                    MessageBox.Show("发生错误:" + e.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    keepalive = false;
                }
            }
            //判断线程是否为活动的
            if (!connected && receive != null && receive.IsAlive)
                //如果是则中止线程
                receive.Abort();
        }
        /// <summary>
        /// 操作当前连接列表
        /// </summary>
        /// <param name="c"></param>
        /// <param name="o"></param>
        private void setChatter(string c, string o)
        {
            //判断是否是创建控件的线程调用
            if (this.lbChatters.InvokeRequired)
            {
                //创建委托
                MyInvoke invoke;
                if (o.CompareTo("add") == 0)
                    invoke = new MyInvoke(addItem);
                else
                    invoke = new MyInvoke(delItem);
                //执行委托
                this.Invoke(invoke, c);
            }
        }
        /// <summary>
        /// 添加连接
        /// </summary>
        /// <param name="c"></param>
        private void addItem(string c)
        {
            this.lbChatters.Items.Add(c);
        }
        /// <summary>
        /// 删除连接
        /// </summary>
        /// <param name="c"></param>
        private void delItem(string c)
        {
            this.lbChatters.Items.Remove(c);
        }
        /// <summary>
        /// 设置连接信息
        /// </summary>
        /// <param name="c"></param>
        private void setInfo(string c)
        {
            //判断是否是创建控件的线程调用
            if (this.rtbChatIn.InvokeRequired)
            {
                MyInvoke invoke = new MyInvoke(setInfo);
                this.Invoke(invoke, c);
            }
            else
            {
                this.rtbChatIn.AppendText(c.ToString());
            }
        }
        /// <summary>
        /// 设置连接状态栏信息
        /// </summary>
        /// <param name="c"></param>
        private void setState(string c)
        {
            //判断是否是创建控件的线程调用
            if (this.statusBar1.InvokeRequired)
            {
                MyInvoke invoke = new MyInvoke(setState);
                this.Invoke(invoke, c);
            }
            else
            {
                //清空当前的连接列表
                this.lbChatters.Items.Clear();
                //发送信息按钮禁用
                btnSend.Enabled = false;
                //断开连接按钮禁用
                btnDisconnect.Enabled = false;
                //更改窗口标题
                this.Text = "客户端";
                this.statusBar1.Text = c;
            }
        }

        /// <summary>
        /// 退出服务器端
        /// </summary>
        private void QuitChat()
        {
            //判断是否为连接状态
            if (connected)
            {
                try
                {
                    //创建消息
                    string command = "GONE|" + clientname;
                    //将消息转化为字节流
                    Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
                    //将消息发送给NetWorkStream
                    ns.Write(outbytes, 0, outbytes.Length);
                }
                catch (Exception e)
                {
                    //提示异常信息
                    MessageBox.Show("发生错误:" + e.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
        }
        //窗口正在关闭
        private void ClientMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            //退出
            QuitChat();
        }
    }
}


 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值