Socket编程---简单的聊天工具

1)Socket编程:

           通过TCP或者UDP协议进行多台主机之间的通讯

           编写程序实现两台电脑之间进行通讯,比如实现一个简单的在线聊天工具

2)聊天工具的开发:

            一台电脑的客户端作为服务器端,另一台电脑作为客户端

      服务器端开启自己电脑的一个端口,监听这其它电脑对这端口的请求

      一旦发现有电脑接入,则建立连接。

                            Socket编程---简单的聊天工具_第1张图片

3)服务器端开启对端口的监听:

           创建一个服务器端的程序,程序开启端口,然后监听

           创建一个叫TalkService的命令行程序,在Main方法里面创建一个IPAddress

    然后开启一个TcpListener监听,执行Start()方法就可以监听了

                                         Socket编程---简单的聊天工具_第2张图片

4)创建客户端并且与服务器端链接:

                 创建一个TalkClient的命令行项目

                 创建一个TalkClient的TCP客户端

                 去链接Connect("127.0.0.1",5000)

                 链接成功则可以读取服务器信息的(通过 tcpClient.Client.LocalEndPoint, tcpClient.Client.RemoteEndPoint)

                客户端这边会自动分配一个端口和服务器这边的5000进行链接,客户端这边的端口不需要程序分配,

          因为每次都可以不一样,服务器端的5000端口是可以和多个客户端链接的。

5)客户端和服务端通信:

                 不仅可以文本字节的传输,还可以文本附件的传输

           5.1) 文本字节的传输:

                  服务器得到一个监听到的链接:

                       服务器一旦发现有人连接上来,则可以获得一个客户端链接

                       调用AcceptTcpClient()方法就可以得到一个客户端链接

                       并且这个方法时中断方法,也就是它会停在那个地方等着有客户端链接进来

                       我们就可以从流中读取客户端信息。

6)客户端实现连续发送自定义的内容:

                     客户端连续输入内容,连续发送到服务器端

7)实现互相对话的方式:

                    客户端可以给服务端发送,服务端也可以给客户端发送

              这个命令行的功能有限,我们的程序只能这样一人说一句,只要这边说完了那边才能跟着说。

TalkService.cs

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;
using System.Net;
using System.Net.Sockets;
using MySql.Data.MySqlClient;
namespace Service
{
    public partial class TalkService : Form
    {
        public TalkService()
        {
            InitializeComponent();
            //不在检查垮了线程的访问控件的东西
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        /*
         *服务器端开启对端口的监听
         */
        IPAddress ip;
        TcpListener listener;
        TcpClient tcpClient;
        private void buttonStart_Click(object sender, EventArgs e)
        {
            //在服务器连接成功开始异步的去运行
            this.backgroundWorker1.RunWorkerAsync();
           }

        /*
         *实现客户端连续发送自定义内容:需要使用多线程
         * 使用backgroundWorker控件属性里面的事件:
         *             DoWork:异步  ProgressChanged:完成以后
         */
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            ip = IPAddress.Parse(this.textBoxIp.Text);//创建IP
            listener = new TcpListener(ip, Convert.ToInt32(this.textBoxPort.Text));//创建TCP监听对象  端口
            /*
             *当出现“以一种访问权限不允许的方式做了一个访问套接字的尝试”原因时因为端口冲突造成的
             */
            listener.Start(); //开始监听
            this.textBoxInfo.Text = "服务器启动-" + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;

            tcpClient = listener.AcceptTcpClient();//中断,等待
            this.textBoxInfo.Text = "连接成功" + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;


            //获取流,并写入byteArray中
            NetworkStream stream = tcpClient.GetStream();
            //创建byteArray数组,bufferSize=1024
            byte[] byteArray = new byte[1024];
            while (true)
            {
                //一直等待客户端传信息,会把流里面的字节数组放到byteArray里面
                int length = stream.Read(byteArray, 0, 1024);  //中端,等待
                //将存放在byte[]的数据转换为字符串,length其实就是客户端发送的字节数组长度
                string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
                this.textBoxInfo.Text = "接收到:" + receiveMessage + "-" + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
            }
   
        }

      
        private void buttonSend_Click(object sender, EventArgs e)
        {
            //拿到用户想要发送的信息
            string message = this.textBoxInput.Text;
            //在界面上呈现
            this.textBoxInfo.Text = "发送:" + message + "-" + DateTime.Now.ToShortDateString() + "\r\n" + this.textBoxInfo.Text;
            //获取流,并写入byteArray中
            NetworkStream stream = tcpClient.GetStream();
            byte[] byteArray = Encoding.Unicode.GetBytes(message);
            //发送了字节数组
            stream.Write(byteArray, 0, byteArray.Length);
        }
    }
}

TalkClient.cs

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;
using MySql.Data.MySqlClient;
using System.Net.Sockets;
 
namespace TalkClient
{
    public partial class TalkClient : Form
    {
        public TalkClient()
        {
            InitializeComponent();
            //不在检查垮了线程的访问控件的东西
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        TcpClient tcpClient;
        private void buttonStart_Click(object sender, EventArgs e)
        {
            try
            {
                tcpClient = new TcpClient();
                tcpClient.Connect(this.textBoxIp.Text, Convert.ToInt32(this.textBoxPort.Text));//连接服务端IP,端口
                this.textBoxInfo.Text = "连接成功" + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
                //在客户端连接成功开始异步的去运行
                this.backgroundWorker1.RunWorkerAsync();
            }
            catch (Exception ex)
            {
                MessageBox.Show("连接失败-" + ex.Message );
            }
           
        }

        private void buttonSend_Click(object sender, EventArgs e)
        {
            //拿到用户想要发送的信息
            string message = this.textBoxInput.Text;
            //在界面上呈现
            this.textBoxInfo.Text = "发送:" + message + "-" + DateTime.Now.ToShortDateString() + "\r\n" + this.textBoxInfo.Text;
            //获取流,并写入byteArray中
            NetworkStream stream = tcpClient.GetStream();
            byte[] byteArray = Encoding.Unicode.GetBytes(message);
            //发送了字节数组
            stream.Write(byteArray,0,byteArray.Length);
        }

        //使用backgroundWorker控件属性里面的事件:DoWork:异步  ProgressChanged:完成以后
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //获取流,并写入byteArray中
            NetworkStream stream = tcpClient.GetStream();
            //创建byteArray数组,bufferSize=1024
            byte[] byteArray = new byte[1024];
            while (true)
            {
                //一直等待客户端传信息,会把流里面的字节数组放到byteArray里面
                int length = stream.Read(byteArray, 0, 1024);  //中端,等待
                //将存放在byte[]的数据转换为字符串,length其实就是客户端发送的字节数组长度
                string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
                this.textBoxInfo.Text = "接收到:" + receiveMessage + "-" + DateTime.Now.ToShortTimeString() + "\r\n" + this.textBoxInfo.Text;
            }
        }
    }
}

 Socket编程---简单的聊天工具_第3张图片                  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Socket)