C# Socket TCP 通信

  • 什么是TCP

两台电脑要互相通讯(比如:QQ聊天)就必须要先建立连接,而建立连接用的就是Socket技术,而建立Socket连接就需要底层协议:TCP协议和UDP协议。这两个协议就是规则,遵循了这个规则就可以建立链接 。

TCP 协议是一种可靠的协议,它保证数据在传输过程中不会丢失或损坏。TCP 协议通过连接的建立、数据的传输和连接的释放等步骤来保证数据的完整性和可靠性。TCP 协议适合于需要数据传输可靠性的场合,例如文件传输、网页浏览等。

UDP 协议是一种不可靠的协议,它不对数据传输的可靠性做出保证。UDP 协议的传输速度比 TCP 更快,但在传输过程中数据可能会丢失或损坏。UDP 协议适合于实时通信,例如视频和音频流的传输。

二者具体的相同点和不同点 如下:

TCP 和UDP 协议相同点:

TCP和UDP都是工作在传输层  

TCP 和 UDP 协议不同点:

UDP协议:无连接、面向报文

优点:速度快、效率高,对资源和CPU占用少

缺点:不可靠,易丢包 

应用场景:语音通话、视频通话(丢个一两帧没事)、VPN等

报文格式:源IP地址+目的IP地址+源端口+目的端口+数据

TCP协议:有连接、面向数据流,连接时需要三次握手、断开时需要四次挥手

优点:安全可靠,不丢数据

缺点:速度慢、效率低、对资源和CPU占用率高

应用场景:发邮件、发文件

数据格式:源端口号+目的端口号+序列号+确认号+数据偏移+标志符

本章着重讲解TCP通信,下一章节再讲解UDP,TCP整体代码框架如下:

服务器端代码:

/*
 * 学习Socket通讯技术
 * 1:概念
 * 2:Tcp通讯原理框架之服务器端编写
 * 
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Socket学习
{
    public class Server
    {
        private Socket _SocketServer;
        private bool _IsListenConnection=true;

        public Server()
        {
            //定义IP地址和端口号
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1000);  //这里端口号最好超过1000,一台电脑有6万多个端口,是从小到大按顺序分配的,本机应用已占用前部分的端口
            _SocketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //绑定IP地址和端口号
            _SocketServer.Bind(endPoint);
            _SocketServer.Listen(10);   //最大可监听10个客户端 
            Console.WriteLine("服务器端已启动...");
            try
            {
                while (_IsListenConnection)
                {                                                              
                    //开始接收客户端消息
                    Socket socketMsgServer = _SocketServer.Accept();     //这里会阻塞线程,所以需要另起线程  
                    Console.WriteLine("有一个客户端连接...");
                    Thread thSocket = new Thread(ClientMsg);
                    thSocket.IsBackground = true;  //将线程设置为后台线程
                    thSocket.Name = "thSocketMsg";
                    thSocket.Start(socketMsgServer);
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 服务器端与客户端的通讯后台线程
        /// </summary>
        /// <param name="socketMsg">表示服务器端的会话Socket</param>
        private void ClientMsg(object sockMsg)
        {
            Socket socketMsg = sockMsg as Socket;

            while (true)
            {
                //准备一个“数据缓存”
                byte[] msgArray = new byte[1024 * 1024]; //1M空间
                //接收客户端发来的数据,返回数据真实的长度
                int trueClientMsgLength = socketMsg.Receive(msgArray);
                //byte数组转string
                string strMsg = Encoding.UTF8.GetString(msgArray, 0, trueClientMsgLength);
                Console.WriteLine("客户端发来数据: "+strMsg);
            }
        }
        static void Main(string[] args)
        {
            Server serverObj = new Server();
        }
    }
}

客户端代码: 

/*
 * 学习Socket通讯技术
 * 1:概念
 * 2:Tcp通讯原理框架之客户端编写
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Socket学习_客户端
{
    public class Client
    {
        private Socket _SocketClient;
        private IPEndPoint serverEndPoint;
        public Client()
        {
            //定义IP地址和端口号
            serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1000);
            _SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                //客户端通过IP地址和端口号连接服务器端
                _SocketClient.Connect(serverEndPoint);
            }
            catch (Exception)
            {

                throw;
            }
            Console.WriteLine("连接服务器端成功!");
        }

        public void SendMsg()
        {
            while (true)
            {
                //要发送给服务端的信息
                string strMsg = Console.ReadLine();
                //如果输入的是"exit"就退出连接
                if (strMsg=="exit")
                {
                    break;
                }
                //字符串转byte数组
                byte[] byteMsg = Encoding.UTF8.GetBytes(strMsg);
                //发送数据
                _SocketClient.Send(byteMsg);
                Console.WriteLine("我:" + strMsg);
            }
            //关闭连接
            _SocketClient.Shutdown(SocketShutdown.Both);
            //清理连接的资源
            _SocketClient.Close();
        }
        static void Main(string[] args)
        {
            Client clientObj = new Client();
            clientObj.SendMsg();
        }
    }
}

整体项目如图(每个项目都是C#控制台应用程序):

运行 步骤:

1、先启动服务端程序:先将TCP服务器端项目设置为启动项,再Ctrl+F5启动

2、再将TCP客户端项目设置为启动项,再Ctrl+F5启动

3、由客户端向服务端发送消息即可

运行结果如下:

目前只能由客户端向服务器端发送消息,无法从服务端向客户端发送消息

下一章讲解UDP通信... 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值