C#构建TCP/IP客户端,服务端

1.Server

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

namespace Server
{
    public partial class Server_Form : Form
    {
        // 负责监听客户端的套接字
        Socket socket_TCP = null;
        // 负责和客户端通信的套接字
        Socket socket_Communication = null;
        //监听线程
        Thread thread_Listen = null;
        //客户端 端口号集合
        Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
        public Server_Form()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;  
        }
        private void button_Connection_Click(object sender, EventArgs e)
        {
            if (button_Connection.Text == "连接")
            {
                button_Connection.Text = "断开";
                socket_TCP = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse(textBox_IP.Text), (int)numericUpDown_Port.Value);
                socket_TCP.Bind(iPEndPoint);
                socket_TCP.Listen(0);
                thread_Listen = new Thread(TCP_Listen);
                thread_Listen.IsBackground = true;
                thread_Listen.Start();
            }
            else if (button_Connection.Text == "断开")
            {
                button_Connection.Text = "连接";
                if (socket_Communication != null)
                {
                    socket_Communication.Close();
                }
            }
        }
        private void TCP_Listen()
        {
            while (true)
            {
                try
                {
                    socket_Communication = socket_TCP.Accept();
                    //客户端网络节点
                    string RemoteEndPoint = socket_Communication.RemoteEndPoint.ToString();
                    dic.Add(RemoteEndPoint, socket_Communication);
                    listBoxOnlineList.Items.Add(RemoteEndPoint);
                    //传参的线程  
                    ParameterizedThreadStart pts = new ParameterizedThreadStart(TCP_Read);
                    Thread thread = new Thread(pts);
                    thread.IsBackground = true;
                    thread.Start(socket_Communication);
                }
                catch (Exception e)
                {
                    break;
                }
            }
        }
        private void button_Send_Click(object sender, EventArgs e)
        {
            if (listBoxOnlineList.SelectedIndex == -1)
            {
                MessageBox.Show("请选择要发送的客户端!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
            else
            {
                string selectClient = listBoxOnlineList.Text;
                TCP_Write(textBox_Send.Text, selectClient);
                textBox_Send.Text = "";
            }
        }
        //获取当前系统时间
        private DateTime GetCurrentTime()
        {
            DateTime currentTime = new DateTime();
            currentTime = DateTime.Now;
            return currentTime;
        }
        private void TCP_Write(string data, string EndPoint)
        {
            try
            {
                //byte[] arrClientSendMsg = new byte[] { 0x11, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC6, 0x9B };
                byte[] arrClientSendMsg = HexStringToByteArray(data);
                dic[EndPoint].Send(arrClientSendMsg);
                richTextBox_Receive.AppendText("本机: " + GetCurrentTime() + "\r\n" + data + "\r\n\n");
                //dic[EndPoint].Send(Encoding.UTF8.GetBytes(data));
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                return;
            }
        }
        private void TCP_Read(object socket_Read)
        {
            Socket socket = socket_Read as Socket;
            while (true)
            {
                try
                {
                    byte[] buffer_Data = new byte[1024 * 1024];
                    int Accept_length = socket.Receive(buffer_Data);
                    List<string> resultArr = new List<string> { };
                    EndPoint endPoint = socket.RemoteEndPoint;
/*                    if (buffer_Data != null && buffer_Data[0] != 0 && buffer_Data[0] != 11)
                    {
                        byte[] arr = buffer_Data.Skip(0).Take(100).ToArray();
                        //byte转16
                        string strRevMsg = byteToHexStr(arr);
                        richTextBox_Receive.AppendText("客户端 " + endPoint + ":" + strRevMsg + "\r\n");
                    }*/
                    //buffer_Data[0] == 11时为485温湿度ID17的返回值
                    //S723型电压电流表的数据处理
                    if (buffer_Data != null && buffer_Data[0] != 0 && buffer_Data[0] != 11)
                    {
                        byte[] arr = buffer_Data.Skip(0).Take(100).ToArray();
                        for(int i = 3;i< arr.Length && arr[i] != 0;)
                        {
                            byte[] floatArr = arr.Skip(i).Take(4).ToArray();
                            string s = byteToHexStr(floatArr);
                            //string转float
                            MatchCollection matches = Regex.Matches(s, @"[0-9A-Fa-f]{2}");
                            byte[] bytes = new byte[matches.Count];
                            for (int j = 0; j < bytes.Length; j++)
                                bytes[j] = byte.Parse(matches[j].Value, System.Globalization.NumberStyles.AllowHexSpecifier);
                            float m = BitConverter.ToSingle(bytes.Reverse().ToArray(), 0);、
                            //保留两位小数
                            string number = m.ToString("0.00");
                            //resultArr对应最终数据的数组,插入数据库即可
                            resultArr.Add(number);
                            i = i + 4;
                        }

                        richTextBox_Receive.AppendText("客户端 " + endPoint + ":" + /*resultArr*/"电压电流数据读取成功" + "\r\n");
                    }
                }
                catch (Exception)
                {
                    //提示套接字监听异常 
                    richTextBox_Receive.AppendText("客户端" + socket.RemoteEndPoint + "已经中断连接" + "\r\n");
                    //移除断开的客户端
                    dic.Remove(socket.RemoteEndPoint.ToString());
                    //从listbox中移除断开连接的客户端
                    listBoxOnlineList.Items.Remove(socket.RemoteEndPoint.ToString());
                    //关闭之前accept出来的和客户端进行通信的套接字
                    socket_Communication.Close();
                    break;
                }
            }
        }

        private void richTextBox_Receive_TextChanged(object sender, EventArgs e)
        {

        }

        /// <summary>
        ///16进制string类型转数组
        /// </summary>
        public static byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
            return buffer;
        }

        /// <summary>
        ///数组转16/10进制字符串
        /// </summary>
        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    //转10进制
                    //returnStr += Convert.ToInt32(bytes[i]);
                    //转16进制
                    returnStr += bytes[i].ToString("X2");//ToString("X2") 转化为大写的16进制
                    //returnStr = returnStr + " ";
                }
            }
            return returnStr;
        }

        /// <summary>
        ///十六进制转为float
        /// </summary>
        public static float ToFloat(byte[] data)
        {
            float a = 0;
            byte i;
            byte[] x = data;
            unsafe
            {
                void* pf;
                fixed (byte* px = x)
                {
                    pf = &a;
                    for (i = 0; i < data.Length; i++)
                    {
                        *((byte*)pf + i) = *(px + i);
                    }
                }
            }
            return a;
        }
        /// <summary>
        /// float转为十六进制
        /// </summary>
        public static byte[] ToByte(float data)
        {
            unsafe
            {
                byte* pdata = (byte*)&data;
                byte[] byteArray = new byte[sizeof(float)];
                for (int i = 0; i < sizeof(float); ++i)
                    byteArray[i] = *pdata++;

                return byteArray;
            }
        }
    }
}

2.Client

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

namespace client
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //关闭对文本框的非法线程操作检查
            TextBox.CheckForIllegalCrossThreadCalls = false;

        }
        //创建 1个客户端套接字 和1个负责监听服务端请求的线程
        Thread threadclient = null;
        Socket socketclient = null;
        List<IPEndPoint> mlist = new List<IPEndPoint>();

        private void btnConnect_Click(object sender, EventArgs e)
        {
            //SocketException exception;
            this.btnConnect.Enabled = false;
            //定义一个套接字监听
            socketclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //获取文本框中的IP地址
            IPAddress address = IPAddress.Parse(txtIP.Text.Trim());

            //将获取的IP地址和端口号绑定在网络节点上
            IPEndPoint point = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));

            try
            {
                //客户端套接字连接到网络节点上,用的是Connect
                socketclient.Connect(point);
            }
            catch (Exception)
            {
                //MessageBox.
                MessageBox.Show("连接失败\r\n");
                this.btnConnect.Enabled = true;
                return;
            }

            threadclient = new Thread(recv);

            threadclient.IsBackground = true;

            threadclient.Start();
        }
        // 接收服务端发来信息的方法 
        private void recv()//
        {
            int x = 0;
            while (true)//持续监听服务端发来的消息
            {
                try
                {
                    //定义一个1M的内存缓冲区,用于临时性存储接收到的消息
                    byte[] arrRecvmsg = new byte[1024 * 1024];

                    //将客户端套接字接收到的数据存入内存缓冲区,并获取长度
                    int length = socketclient.Receive(arrRecvmsg);

                    //将套接字获取到的字符数组转换为人可以看懂的字符串

                    //string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, 0, length);
                    //if(strRevMsg != "")
                    if (arrRecvmsg != null && arrRecvmsg[8] != 0)
                    {
                        //字节太长响应过慢,截取部分
                        byte[] arr = arrRecvmsg.Skip(0).Take(100).ToArray();
                        //byte转16
                        string strRevMsg = byteToHexStr(arr);
                        if (x == 1)
                        {
                            txtRecv.AppendText("服务器:" + GetCurrentTime() + "\r\n" + strRevMsg + "\r\n\n");

                        }
                        else
                        {
                            txtRecv.AppendText(strRevMsg + "\r\n\n");
                            x = 1;
                        }
                    }

                }
                catch (Exception ex)
                {
                    //txtRecv.AppendText("远程服务器已经中断连接" + "\r\n");
                    this.btnConnect.Enabled = true;
                    break;
                }
            }
        }

        //获取当前系统时间
        private DateTime GetCurrentTime()
        {
            DateTime currentTime = new DateTime();
            currentTime = DateTime.Now;
            return currentTime;
        }

        //发送字符信息到服务端的方法
        private void ClientSendMsg(string sendMsg)
        {
            //byte[] arrClientSendMsg = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8b, 0x03, 0x00, 0xc8, 0x00, 0x20};

            //将输入的内容字符串转换为机器可以识别的字节数组   
            byte[] arrClientSendMsg = HexStringToByteArray(sendMsg);
            //byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);
            //调用客户端套接字发送字节数组   
            socketclient.Send(arrClientSendMsg);
            //将发送的信息追加到聊天内容文本框中   
            txtRecv.AppendText(this.txtRecv.Text + "本机: " + GetCurrentTime() + "\r\n" + sendMsg + "\r\n\n");
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            txtRecv.Clear();
            //调用ClientSendMsg方法 将文本框中输入的信息发送给服务端   
            ClientSendMsg(txtSend.Text.Trim());
            //txtSend.Clear();

        }

        private void txtSend_KeyDown(object sender, KeyEventArgs e)
        {
            //当光标位于文本框时 如果用户按下了键盘上的Enter键
            if (e.KeyCode == Keys.Enter)
            {
                //则调用客户端向服务端发送信息的方法  
                ClientSendMsg(txtSend.Text.Trim());
                txtSend.Clear();
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("是否退出?选否,最小化到托盘", "操作提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
            if (result == DialogResult.Yes)
            {
                if (threadclient != null)
                {
                    threadclient.Abort();
                }

                Thread.Sleep(500);
                if (socketclient == null)
                {
                    this.Dispose();
                }
                else
                {
                    socketclient.Close();
                    this.Dispose();
                }
            }
            else if (result == DialogResult.Cancel)
            {
                e.Cancel = true;

            }
            else
            {
                e.Cancel = true;
                this.WindowState = FormWindowState.Minimized;
                this.Visible = false;
                //this.notifyIcon1.Visible = true;
                this.ShowInTaskbar = false;
            }

        }

        //字符串转16进制
        public static byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
            return buffer;
        }

        //十六进制转换为字符串
        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    //转10进制
                    returnStr += Convert.ToInt32(bytes[i]);
                    //转16进制
                    //returnStr += bytes[i].ToString("X2");//ToString("X2") 转化为大写的16进制
                    returnStr = returnStr + " ";
                }
                int a = 1;
            }
            return returnStr;
        }

    }
}

暂时还没添加数据库

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值