- 什么是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通信...