C#使用socket实现服务端实时监听客户端(手动添加的数据在DataGridView上)如何传送数据

时间:2022-11-01 04:45:26
服务端代码:
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.Threading;  
using System.Net;
using System.Net.Sockets;
namespace server
{
    public partial class server : Form
    {
        public server()
        {
           InitializeComponent();  
            //关闭对文本框的非法线程操作检查  
            TextBox.CheckForIllegalCrossThreadCalls = false; 
        }
        Thread threadWatch = null; //负责监听客户端的线程  
        Socket socketWatch = null; //负责监听客户端的套接字
        private void chbLog_CheckedChanged(object sender, EventArgs e)
        {

        }
        //delegate void SetTextCallBack(string text);
        //TcpClient client;
        //NetworkStream stream;
        //private Thread th;  
        private void Form1_Load(object sender, EventArgs e)
        {
            //try
            //{
            //    IPAddress ip = IPAddress.Parse("127.0.0.1");
            //    TcpListener server = new TcpListener(ip, 5555);
            //    txtState.Text = "启动服务器成功\r\n";
            //    server.Start();
            //    client = server.AcceptTcpClient();
            //    stream = client.GetStream();
            //    th = new Thread(new ThreadStart(Run));
            //    th.Start();
            //}
            //catch
            //{
            //     txtState.Text ="启动服务器失败";





            //定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)  
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //服务端发送信息 需要1个IP地址和端口号  
            IPAddress ipaddress = IPAddress.Parse("127.0.0.1"); //获取文本框输入的IP地址  

            //将IP地址和端口号绑定到网络节点endpoint上   
            IPEndPoint endpoint = new IPEndPoint(ipaddress,8081); //获取文本框上输入的端口号  

            //监听绑定的网络节点  
            socketWatch.Bind(endpoint);

            //将套接字的监听队列长度限制为20  
            socketWatch.Listen(20);

            //创建一个监听线程   
            threadWatch = new Thread(WatchConnecting);

            //将窗体线程设置为与后台同步  
            threadWatch.IsBackground = true;

            //启动线程  
            threadWatch.Start();

            //启动线程后 txtMsg文本框显示相应提示  
            txtState.AppendText("开始监听客户端传来的信息!"); 
        }
        //创建一个负责和客户端通信的套接字   
        Socket socConnection = null;  


         /// <summary>  
        /// 监听客户端发来的请求  
        /// </summary>  
        private void WatchConnecting()  
        {  
            while (true)  //持续不断监听客户端发来的请求  
            {  
                socConnection = socketWatch.Accept();
                txtState.AppendText("客户端连接成功" + "\r\n");  
                //创建一个通信线程   
                ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg);  
                Thread thr = new Thread(pts);  
                thr.IsBackground = true;  
                //启动线程  
                thr.Start(socConnection);  
            }  
        }


        ///// <summary>  
        ///// 发送信息到客户端的方法  
        ///// </summary>  
        ///// <param name="sendMsg">发送的字符串信息</param>  
        //private void ServerSendMsg(string sendMsg)
        //{
        //    //将输入的字符串转换成 机器可以识别的字节数组  
        //    byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg);
        //    //向客户端发送字节数组信息  
        //    socConnection.Send(arrSendMsg);
        //    //将发送的字符串信息附加到文本框txtMsg上  
        //    txtState.AppendText("So-flash:" + GetCurrentTime() + "\r\n" + sendMsg + "\r\n");
        //}

        /// <summary>  
        /// 接收客户端发来的信息   
        /// </summary>  
        /// <param name="socketClientPara">客户端套接字对象</param>  
        private void ServerRecMsg(object socketClientPara)
        {
            Socket socketServer = socketClientPara as Socket;
            while (true)
            {
                try
                {
                    //创建一个内存缓冲区 其大小为1024*1024字节  即1M  
                    byte[] arrServerRecMsg = new byte[1024 * 1024];

                    //将接收到的信息存入到内存缓冲区,并返回其字节数组的长度  
                    int length = socketServer.Receive(arrServerRecMsg);

                    //将机器接受到的字节数组转换为人可以读懂的字符串  
                    string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
                    //将发送的字符串信息附加到DataGridView上   
                    DataGridViewRow dgvr3 = new DataGridViewRow();
                    dgvr3.CreateCells(dgvView);
                    dgvr3.Cells[0].Value = DateTime.Now;
                    dgvr3.Cells[1].Value = "0";
                    dgvr3.Cells[2].Value = strSRecMsg;
                    this.dgvView.Rows.Add(dgvr3);
                }
                catch (Exception)
                {

                    MessageBox.Show("客户端断开连接");
                    this.Close();
                    break;
                }
                    
            }
        }

        //}

        // private void SetText(string text)  
        //{  
        //    //richTextBox1.AppendText("客户端对服务端说:" + text + "\r\n");  
        //      DataGridViewRow dgvr = new DataGridViewRow();
        //    foreach (DataGridViewColumn c in this.dgvView.Columns)
        //    {
        //        dgvr.Cells.Add(c.CellTemplate.Clone() as DataGridViewCell);
        //    }
        //    dgvr.Cells[0].Value = DateTime.Now;
        //    dgvr.Cells[1].Value = "0";
        //    dgvr.Cells[2].Value = "0";
        //    dgvr.Cells[3].Value = "0";
        //    dgvr.Cells[4].Value = text;
        //    this.dgvView.Rows.Add(dgvr);
        //} 

        //private void Run()
        //{
        //    string msg = string.Empty;
        //    if (client.Connected)
        //    {
        //        while (true)
        //        {
        //            try
        //            {
        //                byte[] data = new byte[256];
        //                Int32 bytes = stream.Read(data, 0, data.Length);
        //                msg = Encoding.Unicode.GetString(data, 0, bytes);
        //                this.Invoke(new SetTextCallBack(SetText), msg);
        //            }
        //            catch
        //            {
        //                break;
                        

        //            }
        //        }
        //    }
        //} 
  
     }

   }
客户端代码: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 System.Threading;  
namespace View
{
    public partial class frmView : Form
    {
        public frmView()
        {
            InitializeComponent();
        }
        //delegate void SetTextCallBack(string text);
        //TcpClient client;
        //NetworkStream stream;
        //private Thread th;  
        Socket socketClient = null;

        private void view_Load(object sender, EventArgs e)
        {


            DataGridViewRow dgvr = new DataGridViewRow();
            dgvr.CreateCells(dgvView);
            dgvr.Cells[0].Value = DateTime.Now;
            dgvr.Cells[1].Value = "0";
            dgvr.Cells[2].Value = "0";
            dgvr.Cells[3].Value = "0";
            dgvr.Cells[4].Value = "0 交易缩写:IINQ,商户号:105440157320061,卡号:0010210689800000111,网关流水:006581,响应码:00";
            this.dgvView.Rows.Add(dgvr);


            DataGridViewRow dgvr1 = new DataGridViewRow();
            dgvr1.CreateCells(dgvView);
            dgvr1.Cells[0].Value = DateTime.Now;
            dgvr1.Cells[1].Value = "0";
            dgvr1.Cells[2].Value = "0";
            dgvr1.Cells[3].Value = "0";
            dgvr1.Cells[4].Value = "0 交易缩写:IINQ,商户号:205440157320061,卡号:0010210689800000111,网关流水:006581,响应码:00";
            this.dgvView.Rows.Add(dgvr1);

            DataGridViewRow dgvr2 = new DataGridViewRow();
            dgvr2.CreateCells(dgvView);
            dgvr2.Cells[0].Value = DateTime.Now;
            dgvr2.Cells[1].Value = "0";
            dgvr2.Cells[2].Value = "0";
            dgvr2.Cells[3].Value = "0";
            dgvr2.Cells[4].Value = "0 交易缩写:IINQ,商户号:305440157320061,卡号:0010210689800000111,网关流水:006581,响应码:00";
            this.dgvView.Rows.Add(dgvr2);

            DataGridViewRow dgvr3 = new DataGridViewRow();
            dgvr3.CreateCells(dgvView);
            dgvr3.Cells[0].Value = DateTime.Now;
            dgvr3.Cells[1].Value = "0";
            dgvr3.Cells[2].Value = "0";
            dgvr3.Cells[3].Value = "0";
            dgvr3.Cells[4].Value = "0 交易缩写:IINQ,商户号:405440157320061,卡号:0010210689800000111,网关流水:006581,响应码:00";
            this.dgvView.Rows.Add(dgvr3);
               

               //定义一个套字节监听  包含3个参数(IP4寻址协议,流式连接,TCP协议)  
               socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

               //需要获取文本框中的IP地址  
               IPAddress ipaddress = IPAddress.Parse("127.0.0.1");

               //将获取的ip地址和端口号绑定到网络节点endpoint上  
               IPEndPoint endpoint = new IPEndPoint(ipaddress, 8081);

               //这里客户端套接字连接到网络节点(服务端)用的方法是Connect 而不是Bind  
               socketClient.Connect(endpoint);

               for (int i = 1; i < dgvView.Rows.Count;i++ )
               {
                   //将输入的内容字符串转换为机器可以识别的字节数组  
                   byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(dgvr3.Cells[4].Value.ToString());

                   //调用客户端套接字发送字节数组  
                   socketClient.Send(arrClientSendMsg);
               }

          
          
               
              
              

               //传送数据到服务端
               // ClientSendMsg(dgvr.Cells[0].Value.ToString());
               
               
          
        }






       
        private void btnCleak_Click(object sender, EventArgs e)
        {
            dgvView.Rows.Clear();
        }

    }
}

2 个解决方案

#1


记录最后发送的行的index,单元格changed事件里判断之后的行是否满足发送要求,满足了发送

#2


         //定义一个套字节监听  包含3个参数(IP4寻址协议,流式连接,TCP协议)  
            socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //需要获取文本框中的IP地址  
            IPAddress ipaddress = IPAddress.Parse("127.0.0.1");

            //将获取的ip地址和端口号绑定到网络节点endpoint上  
            IPEndPoint endpoint = new IPEndPoint(ipaddress, 8081);

            //这里客户端套接字连接到网络节点(服务端)用的方法是Connect 而不是Bind  
            socketClient.Connect(endpoint);

            DataTable dt = new DataTable();
            dt.Columns.Add("日期");
            dt.Columns.Add("进程");
            dt.Columns.Add("错误码");
            dt.Columns.Add("信息索引");
            dt.Columns.Add("信息");
            this.dgvView.DataSource = dt;

            for (int i = 0; i <6;i++ )
            {

                DataRow dr = dt.NewRow();
                dr[0] = DateTime.Now;
                dr[1] = "0";
                dr[2] = "dddd";
                dr[3] = "dfsfsfsdfasfdsf";
                dr[4] = i+"dfsfdsdfsafd";
                dt.Rows.Add(dr);
                //将输入的内容字符串转换为机器可以识别的字节数组  
                byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(dr[4].ToString());
                //调用客户端套接字发送字节数组  
                socketClient.Send(arrClientSendMsg);
            } 
我又改用这个方法向服务端传数据了 但是服务端总是丢失数据

这是服务端的
   private void Form1_Load(object sender, EventArgs e)
        {
            //try
            //{
            //    IPAddress ip = IPAddress.Parse("127.0.0.1");
            //    TcpListener server = new TcpListener(ip, 5555);
            //    txtState.Text = "启动服务器成功\r\n";
            //    server.Start();
            //    client = server.AcceptTcpClient();
            //    stream = client.GetStream();
            //    th = new Thread(new ThreadStart(Run));
            //    th.Start();
            //}
            //catch
            //{
            //     txtState.Text ="启动服务器失败";




            dt= new DataTable();
            dt.Columns.Add("日期");
            dt.Columns.Add("进程");
            dt.Columns.Add("错误码");
            dt.Columns.Add("信息索引");
            dt.Columns.Add("信息");
            this.dgvView.DataSource = dt;
            //定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)  
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //服务端发送信息 需要1个IP地址和端口号  
            IPAddress ipaddress = IPAddress.Parse("127.0.0.1"); //获取文本框输入的IP地址  

            //将IP地址和端口号绑定到网络节点endpoint上   
            IPEndPoint endpoint = new IPEndPoint(ipaddress,8081); //获取文本框上输入的端口号  

            //监听绑定的网络节点  
            socketWatch.Bind(endpoint);

            //将套接字的监听队列长度限制为20  
            socketWatch.Listen(20);

            //创建一个监听线程   
            threadWatch = new Thread(WatchConnecting);

            //将窗体线程设置为与后台同步  
            threadWatch.IsBackground = true;

            //启动线程  
            threadWatch.Start();

            //启动线程后 txtMsg文本框显示相应提示  
            txtState.AppendText("开始监听客户端传来的信息!"); 
        }
        //创建一个负责和客户端通信的套接字   
        Socket socConnection = null;  


         /// <summary>  
        /// 监听客户端发来的请求  
        /// </summary>  
        private void WatchConnecting()  
        {  
            while (true)  //持续不断监听客户端发来的请求  
            {  
                socConnection = socketWatch.Accept();
                txtState.AppendText("客户端连接成功" + "\r\n");  
                //创建一个通信线程   
                ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg);  
                Thread thr = new Thread(pts);  
                thr.IsBackground = true;  
                //启动线程  
                thr.Start(socConnection);  
            }  
        }


        ///// <summary>  
        ///// 发送信息到客户端的方法  
        ///// </summary>  
        ///// <param name="sendMsg">发送的字符串信息</param>  
        //private void ServerSendMsg(string sendMsg)
        //{
        //    //将输入的字符串转换成 机器可以识别的字节数组  
        //    byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg);
        //    //向客户端发送字节数组信息  
        //    socConnection.Send(arrSendMsg);
        //    //将发送的字符串信息附加到文本框txtMsg上  
        //    txtState.AppendText("So-flash:" + GetCurrentTime() + "\r\n" + sendMsg + "\r\n");
        //}

        /// <summary>  
        /// 接收客户端发来的信息   
        /// </summary>  
        /// <param name="socketClientPara">客户端套接字对象</param>  
        private void ServerRecMsg(object socketClientPara)
        {
            Socket socketServer = socketClientPara as Socket;
            while (true)
            {
                try
                {

                    //创建一个内存缓冲区 其大小为1024*1024字节  即1M  
                    byte[] arrServerRecMsg = new byte[1024 * 1024];

                    //将接收到的信息存入到内存缓冲区,并返回其字节数组的长度  
                    int length = socketServer.Receive(arrServerRecMsg);

                    //将机器接受到的字节数组转换为人可以读懂的字符串  
                    string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
                    //将发送的字符串信息附加到DataGridView上   
                    //DataGridViewRow dgvr3 = new DataGridViewRow();
                    //dgvr3.CreateCells(dgvView);
                    //dgvr3.Cells[0].Value = DateTime.Now;
                    //dgvr3.Cells[1].Value = "0";
                    //dgvr3.Cells[2].Value = strSRecMsg;
                    //this.dgvView.Rows.Add(dgvr3);

                    DataRow dr = dt.NewRow();
                    dr[0] = DateTime.Now;
                    dr[1] = "0";
                    dr[2] = "0";
                    dr[3] = "0";
                    dr[4] = strSRecMsg;
                    dt.Rows.Add(dr);
        
                }
                catch (Exception)
                {

                    MessageBox.Show("客户端断开连接");
                    this.Close();
                    break;
                }
                    
            }
        }

#1


记录最后发送的行的index,单元格changed事件里判断之后的行是否满足发送要求,满足了发送

#2


         //定义一个套字节监听  包含3个参数(IP4寻址协议,流式连接,TCP协议)  
            socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //需要获取文本框中的IP地址  
            IPAddress ipaddress = IPAddress.Parse("127.0.0.1");

            //将获取的ip地址和端口号绑定到网络节点endpoint上  
            IPEndPoint endpoint = new IPEndPoint(ipaddress, 8081);

            //这里客户端套接字连接到网络节点(服务端)用的方法是Connect 而不是Bind  
            socketClient.Connect(endpoint);

            DataTable dt = new DataTable();
            dt.Columns.Add("日期");
            dt.Columns.Add("进程");
            dt.Columns.Add("错误码");
            dt.Columns.Add("信息索引");
            dt.Columns.Add("信息");
            this.dgvView.DataSource = dt;

            for (int i = 0; i <6;i++ )
            {

                DataRow dr = dt.NewRow();
                dr[0] = DateTime.Now;
                dr[1] = "0";
                dr[2] = "dddd";
                dr[3] = "dfsfsfsdfasfdsf";
                dr[4] = i+"dfsfdsdfsafd";
                dt.Rows.Add(dr);
                //将输入的内容字符串转换为机器可以识别的字节数组  
                byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(dr[4].ToString());
                //调用客户端套接字发送字节数组  
                socketClient.Send(arrClientSendMsg);
            } 
我又改用这个方法向服务端传数据了 但是服务端总是丢失数据

这是服务端的
   private void Form1_Load(object sender, EventArgs e)
        {
            //try
            //{
            //    IPAddress ip = IPAddress.Parse("127.0.0.1");
            //    TcpListener server = new TcpListener(ip, 5555);
            //    txtState.Text = "启动服务器成功\r\n";
            //    server.Start();
            //    client = server.AcceptTcpClient();
            //    stream = client.GetStream();
            //    th = new Thread(new ThreadStart(Run));
            //    th.Start();
            //}
            //catch
            //{
            //     txtState.Text ="启动服务器失败";




            dt= new DataTable();
            dt.Columns.Add("日期");
            dt.Columns.Add("进程");
            dt.Columns.Add("错误码");
            dt.Columns.Add("信息索引");
            dt.Columns.Add("信息");
            this.dgvView.DataSource = dt;
            //定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)  
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //服务端发送信息 需要1个IP地址和端口号  
            IPAddress ipaddress = IPAddress.Parse("127.0.0.1"); //获取文本框输入的IP地址  

            //将IP地址和端口号绑定到网络节点endpoint上   
            IPEndPoint endpoint = new IPEndPoint(ipaddress,8081); //获取文本框上输入的端口号  

            //监听绑定的网络节点  
            socketWatch.Bind(endpoint);

            //将套接字的监听队列长度限制为20  
            socketWatch.Listen(20);

            //创建一个监听线程   
            threadWatch = new Thread(WatchConnecting);

            //将窗体线程设置为与后台同步  
            threadWatch.IsBackground = true;

            //启动线程  
            threadWatch.Start();

            //启动线程后 txtMsg文本框显示相应提示  
            txtState.AppendText("开始监听客户端传来的信息!"); 
        }
        //创建一个负责和客户端通信的套接字   
        Socket socConnection = null;  


         /// <summary>  
        /// 监听客户端发来的请求  
        /// </summary>  
        private void WatchConnecting()  
        {  
            while (true)  //持续不断监听客户端发来的请求  
            {  
                socConnection = socketWatch.Accept();
                txtState.AppendText("客户端连接成功" + "\r\n");  
                //创建一个通信线程   
                ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg);  
                Thread thr = new Thread(pts);  
                thr.IsBackground = true;  
                //启动线程  
                thr.Start(socConnection);  
            }  
        }


        ///// <summary>  
        ///// 发送信息到客户端的方法  
        ///// </summary>  
        ///// <param name="sendMsg">发送的字符串信息</param>  
        //private void ServerSendMsg(string sendMsg)
        //{
        //    //将输入的字符串转换成 机器可以识别的字节数组  
        //    byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg);
        //    //向客户端发送字节数组信息  
        //    socConnection.Send(arrSendMsg);
        //    //将发送的字符串信息附加到文本框txtMsg上  
        //    txtState.AppendText("So-flash:" + GetCurrentTime() + "\r\n" + sendMsg + "\r\n");
        //}

        /// <summary>  
        /// 接收客户端发来的信息   
        /// </summary>  
        /// <param name="socketClientPara">客户端套接字对象</param>  
        private void ServerRecMsg(object socketClientPara)
        {
            Socket socketServer = socketClientPara as Socket;
            while (true)
            {
                try
                {

                    //创建一个内存缓冲区 其大小为1024*1024字节  即1M  
                    byte[] arrServerRecMsg = new byte[1024 * 1024];

                    //将接收到的信息存入到内存缓冲区,并返回其字节数组的长度  
                    int length = socketServer.Receive(arrServerRecMsg);

                    //将机器接受到的字节数组转换为人可以读懂的字符串  
                    string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
                    //将发送的字符串信息附加到DataGridView上   
                    //DataGridViewRow dgvr3 = new DataGridViewRow();
                    //dgvr3.CreateCells(dgvView);
                    //dgvr3.Cells[0].Value = DateTime.Now;
                    //dgvr3.Cells[1].Value = "0";
                    //dgvr3.Cells[2].Value = strSRecMsg;
                    //this.dgvView.Rows.Add(dgvr3);

                    DataRow dr = dt.NewRow();
                    dr[0] = DateTime.Now;
                    dr[1] = "0";
                    dr[2] = "0";
                    dr[3] = "0";
                    dr[4] = strSRecMsg;
                    dt.Rows.Add(dr);
        
                }
                catch (Exception)
                {

                    MessageBox.Show("客户端断开连接");
                    this.Close();
                    break;
                }
                    
            }
        }