`
444878909
  • 浏览: 637788 次
文章分类
社区版块
存档分类
最新评论

网络编程之TCP异步群聊:客户端代码

 
阅读更多

最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档。于是我也觉的有这个必要。写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客。

该程序可以在公共网络上运行,只要输入服务器的IP地址即可。

程序不是很难,由于时间过了一年多了,现在也不好详细讲解了。就贴一下代码,程序还是很容易理解的,看英文单词就知道代码的意思了。


服务器代码在:http://blog.csdn.net/arsenal1109389480/article/details/12399803


第一步:建一个Winform程序

第二步:添加一个类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net.Sockets;

namespace Client
{
    class ReadObject
    {
        public NetworkStream netStream;
        public byte[] bytes;
        public ReadObject(NetworkStream netStream, int bufferSize)
        {
            this.netStream = netStream;
            bytes = new byte[bufferSize];
        }
    }
}


第三步:客户端代码

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

using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Client
{
    public partial class Client : Form
    {
        private bool isExit = false;
        private TcpClient client;
        private NetworkStream networkStream;

        private EventWaitHandle allDone =
            new EventWaitHandle(false, EventResetMode.ManualReset);

        private delegate void SetRichtextBoxRecieve(string str);
        SetRichtextBoxRecieve setrichtextboxrecieve;
        private delegate void SetRichtextBoxSend(string str);
        SetRichtextBoxSend setrichtextboxsend;
        private delegate void SetRichtextBoxStatus(string str);
        SetRichtextBoxStatus setrichtextboxstatu;

        public Client()
        {
            InitializeComponent();
            buttonStart.Enabled = true;
            buttonSend.Enabled = false;
            buttonStop.Enabled = true;

            setrichtextboxrecieve = new SetRichtextBoxRecieve(RecieceRichtextBox);
            setrichtextboxsend = new SetRichtextBoxSend(SendRichtextBox);
            setrichtextboxstatu = new SetRichtextBoxStatus(StatuRichtextBox);
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            client = new TcpClient(AddressFamily.InterNetwork);

            AsyncCallback requestCallback = new AsyncCallback(RequestCallback);

            allDone.Reset();

            client.BeginConnect(textBoxIP.Text, Convert.ToInt32(textBoxPort.Text), requestCallback, client);

            richTextBoxStatu.Invoke(setrichtextboxstatu, string.Format("本机EndPoint:{0}",
               client.Client.LocalEndPoint));
            richTextBoxStatu.Invoke(setrichtextboxstatu, "开始与服务器建立连接");

            allDone.WaitOne();

            buttonSend.Enabled = true;
            buttonStart.Enabled = false;
            buttonStop.Enabled = true;
        }

        private void RequestCallback(IAsyncResult ar)
        {
            allDone.Set();
            try
            {
                client = (TcpClient)ar.AsyncState;
                client.EndConnect(ar);

                richTextBoxStatu.Invoke(setrichtextboxstatu,
                    string.Format("与服务器{0}连接成功", client.Client.RemoteEndPoint));

                networkStream = client.GetStream();

                ReadObject readobject =
                    new ReadObject(networkStream, client.ReceiveBufferSize);

                networkStream.BeginRead(readobject.bytes,
                    0, readobject.bytes.Length, ReadCallback, readobject);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }

        private void ReadCallback(IAsyncResult ar)
        {
            try
            {
                ReadObject readobject = (ReadObject)ar.AsyncState;
                int count = readobject.netStream.EndRead(ar);

                richTextBoxRecieve.Invoke(setrichtextboxrecieve,
                    System.Text.Encoding.UTF8.GetString(readobject.bytes, 0, count));

                if (isExit == false)
                {
                    //重新调用BeginRead进行异步读取
                    readobject = new ReadObject(networkStream, client.ReceiveBufferSize);
                    networkStream.BeginRead(readobject.bytes,
                        0, readobject.bytes.Length, ReadCallback, readobject);
                }
            }
            catch
            {
                MessageBox.Show("与服务器断开连接!");
            }
        }

        private void SendString(string str)
        {
            try
            {
                byte[] bytesData = System.Text.Encoding.UTF8.GetBytes(str);
                networkStream.BeginWrite(bytesData,
                    0, bytesData.Length, new AsyncCallback(SendCallback), networkStream);
                networkStream.Flush();
            }
            catch(Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }

        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                networkStream.EndWrite(ar);
            }
            catch
            {
                MessageBox.Show("已断开连接!");
            }
        }

        private void StatuRichtextBox(string str)
        {
            richTextBoxStatu.AppendText(str+"\r\n");
        }
        private void SendRichtextBox(string str)
        {
            richTextBoxSend.AppendText(str + "\r\n");
        }
        private void RecieceRichtextBox(string str)
        {
            richTextBoxRecieve.AppendText(str + "\r\n");
        }

        private void buttonSend_Click(object sender, EventArgs e)
        {
            SendString(richTextBoxSend.Text);
            richTextBoxSend.Clear();
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            try
            {
                SendString(textBoxUser.Text + "离开了房间!!");
                networkStream.Close();
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }

            buttonSend.Enabled = false;
            buttonStart.Enabled = true;
            buttonStop.Enabled = false;
        }

        private void Client_FormClosing(object sender, FormClosingEventArgs e)
        {
            isExit = true;
            allDone.Set();
        }

        private void buttonSend_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyValue == 13)
            {
                e.Handled = true;
                buttonSend_Click(this, null);
            }
        }
    }
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics