C# TCP服务器和客户端

本文介绍如何使用C#实现TCP通信,包括服务器和客户端的搭建过程,并解释了七层网络模型及TCP协议的基本概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 七层协议

  • 应用层
  • 表示层
  • 会话层
  • 传输层
  • 网络层
  • 数据链路层
  • 物理层
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层

TCP/UDP属于传输层,IP属于网络层

2. TCP协议

建立有连接的,可靠性高的,无数据丢失的连接。

3. 使用C#实现TCP

3.1 服务器

  1. 初始化套接字
  2. 绑定IP、端口号
  3. 监听
  4. 接收客户请求
  5. 收发数据
  6. 关闭套接字
    在这里插入图片描述
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 SocketTCPService
{

    public partial class ServerForm : Form
    {
        Socket server;//服务器套接字
        Socket client;//接受客户请求后的套接字
        byte[] buffer = new byte[1024 * 1024 * 6];//申请6Mb内存
        Thread th;//监听线程
        Thread receive;//接收数据线程
        Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
        public ServerForm()
        {
            InitializeComponent();
        }

        #region 启动服务器
        bool isSer = false;
        private void buttonStartServer_Click(object sender, EventArgs e)
        {
            if(!isSer)
            {
                //1. 初始化套接字
                server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                //2. 绑定套接字和端口号
                IPAddress ip = IPAddress.Parse(textBoxServerIP.Text);
                int port = Convert.ToInt32(textBoxServerPort.Text);
                server.Bind(new IPEndPoint(ip, port));
                //3. 监听
                server.Listen(10);
                //4. 开启监听线程
                th = new Thread(new ThreadStart(ListenC));
                th.IsBackground = true;//设置为后台线程,不需要用户主动关闭
                th.Start();
                isSer = true;
                buttonStartServer.Text = "关闭服务器";
                buttonStartServer.BackColor = Color.GreenYellow;
            }
            else
            {
                if(server != null)
                {
                    server.Close();
                    server = null;
                }
                if (client != null)
                {
                    client.Close();
                    client = null;
                }
                if(th != null)
                {
                    th.Abort();
                }
                if (receive != null)
                {
                    receive.Abort();
                }
                isSer = false;
                buttonStartServer.Text = "启动服务器";
                buttonStartServer.BackColor = Color.LightGray;
            }
        }
        #endregion

        #region 监听线程
        public void ListenC()
        {
            try
            {
                while (true)
                {
                    //等待客户的连接请求
                    client = server.Accept();//阻塞等待

                    dict.Add(client.RemoteEndPoint.ToString(), client);

                    //连接成功
                    Invoke(new MethodInvoker(delegate ()
                    {
                        listBoxReceive.Items.Add("连接成功");
                        comboBoxClient.Items.Add(client.RemoteEndPoint.ToString());
                    }));
                    
                    //开启线程
                    receive = new Thread(new ParameterizedThreadStart(RecData));
                    receive.IsBackground = true;
                    receive.Start(client);
                }
            }
            catch (Exception)
            {
                //throw;
            }
        }
        #endregion

        #region 接收数据线程
        public void RecData(object obj)
        {
            Socket Client = (Socket)obj;
            int counts = 0;
            while (true)
            {
                try
                {
                    //6. 接收数据
                    counts = Client.Receive(buffer);
                    if (counts > 0)
                    {
                        //在控件上显示接收到的数据(字符串)
                        Invoke(new MethodInvoker(delegate ()
                        {
                            listBoxReceive.Items.Add(string.Format("客户端{0}说:{1}",
                                Client.RemoteEndPoint.ToString(), Encoding.Default.GetString(buffer,0,counts)));
                        }));
                    }
                }
                catch(Exception)
                {
                    //throw;
                }
            }
        }
        #endregion

        #region 发送数据
        private void buttonSend_Click(object sender, EventArgs e)
        {
            if(!isSer)
            {
                MessageBox.Show("未启动服务器");
            }
            string ip = comboBoxClient.SelectedItem.ToString();            
            byte[] buffer = Encoding.Default.GetBytes(textBoxSend.Text);
            dict[ip].Send(buffer);
            //client.Send(buffer);
        }
        #endregion

        private void buttonClear_Click(object sender, EventArgs e)
        {
            listBoxReceive.Items.Clear();
        }
    }
}

3.2 客户端

  1. 初始化套接字
  2. 连接服务器
  3. 收发数据
  4. 关闭套接字

在这里插入图片描述

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 SocketTCPClient
{
    public partial class FormClient : Form
    {
        #region 构造函数
        public FormClient()
        {
            InitializeComponent();
        }
        #endregion

        #region 变量
        Socket ClientSocket;//套接字
        byte[] buffer = new byte[1024 * 1024 * 6];
        bool isConnect = false;
        Thread th;
        #endregion

        #region 连接服务器 初始化套接字
        private void buttonConnect_Click(object sender, EventArgs e)
        {
            try
            {
                if(!isConnect)
                {
                    //1. 初始化套接字
                    ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    //2. 连接服务器
                    IPAddress ip = IPAddress.Parse(textBoxIP.Text);
                    int port = Convert.ToInt32(textBoxPort.Text);
                    ClientSocket.Connect(new IPEndPoint(ip, port));
                    isConnect = true;
                    buttonConnect.Text = "断开服务器";
                    buttonConnect.BackColor = Color.LawnGreen;

                    //3. 开启线程
                    th = new Thread(RecData);
                    th.IsBackground = true;
                    th.Start();
                }
                else
                {
                    if (ClientSocket != null)
                    {
                        ClientSocket.Close();
                        isConnect = false;
                        buttonConnect.Text = "连接服务器";
                        buttonConnect.BackColor = Color.LightGray;
                    }
                    if(th != null)
                    {
                        th.Abort();
                        th = null;
                    }                       
                }
            }
            catch (Exception)
            {
                MessageBox.Show("连接失败,请检查是否启动了服务器", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                //throw;
            }
        }
        #endregion

        #region 接收数据线程
        public void RecData()
        {            
            int counts = 0;
            while (true)
            {
                counts = ClientSocket.Receive(buffer);
                if (counts > 0)
                {
                    Invoke(new MethodInvoker(delegate ()
                    {
                        listBoxRec.Items.Add(string.Format("服务器说:{0}",Encoding.Default.GetString(buffer,0,counts)));
                    }));
                }
            }
        }
        #endregion

        #region 发送
        private void buttonSend_Click(object sender, EventArgs e)
        {
            if(isConnect)
            {
                byte[] buffer = Encoding.Default.GetBytes(textBoxSend.Text);
                ClientSocket.Send(buffer);
            }
            else
            {
                MessageBox.Show("客户端未连接到服务器", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        private void buttonClear_Click(object sender, EventArgs e)
        {
            listBoxRec.Items.Clear();
        }
    }
}

4. 资源下载地址

https://download.youkuaiyun.com/download/weixin_38566632/18594194

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MechMaster

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值