我们常用的网络通信方式一般包括HTTP通信和Socket通讯,这边主要讲解socket通讯方式。
socket方式分为两种:面向连接的TCP和无连接的服务UDP。
简介参考:https://www.cnblogs.com/KevinBran/p/10641362.html
C#中Tcp和Udp,既可以通过TcpClient和UdpClient类实现,也可以用Socket类。
Demo下载链接:https://download.csdn.net/download/wangningzk123/12549263
Tcp客户端:
Socket clientSocket; //服务器端socket
IPAddress ip; //主机ip
IPEndPoint ipEnd;
string recvStr; //接收的字符串
byte[] recvData = new byte[10240]; //接收的数据,必须为字节
int recvLen; //接收的数据长度
Thread connectThread; //连接线程
//初始化
void Start()
{
//本机IP和端口
string address = "192.168.0.113";
int port = 10001;
//定义服务器的IP和端口,端口与服务器对应
ip = IPAddress.Parse(address); //可以是局域网或互联网ip,此处是本机
ipEnd = new IPEndPoint(ip, port); //服务器端口号
//SocketConnet();
//开启一个线程连接,必须的,否则主线程卡死
connectThread = new Thread(new ThreadStart(SocketReceive));
connectThread.Start();
}
void SocketConnet()
{
if (clientSocket != null)
clientSocket.Close();
//定义套接字类型,必须在子线程中定义
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//连接
//serverSocket.Connect(ipEnd);
异步连接,连接成功调用connectCallback方法
IAsyncResult result = clientSocket.BeginConnect(ipEnd, new AsyncCallback(ConnectCallback), clientSocket);
这里做一个超时的监测,当连接超过5秒还没成功表示超时
bool success = result.AsyncWaitHandle.WaitOne(5000, true);
if (!success)
{
//超时
SocketConnet();
}
}
private void ConnectCallback(IAsyncResult asyncConnect)
{
SocketSend("hello server i am No 1");
}
public void SocketSend(string msg)//SocketSend(, T instance)
{
//清空发送缓存
//sendData = new byte[1024];
//数据类型转换
//sendData = Encoding.ASCII.GetBytes(sendStr);
if (!clientSocket.Connected)
{
return;
}
byte[] buffer = Encoding.Unicode.GetBytes(msg);//将字符串转化为二进制
//发送
//serverSocket.Send(sendData, sendData.Length, SocketFlags.None);
IAsyncResult asyncSend = clientSocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientSocket);
}
private void SendCallback(IAsyncResult asyncConnect)
{
}
void SocketReceive()
{
SocketConnet();
//不断接收服务器发来的数据
while (true)
{
try
{
Array.Clear(recvData, 0, recvData.Length);
recvLen = clientSocket.Receive(recvData);
if (recvLen <= 0)
{
break;
}
//Tcp 接受服务器数据,需要自己组装 -------------------------------------------------------
recvStr = Encoding.Unicode.GetString(recvData);
//-------------------------------------------------------
}
catch (Exception ex)
{
return;
}
}
}
Tcp服务器:
Socket serverSocket;
Socket []accpetSocket;
IPAddress ip; //主机ip
IPEndPoint ipEnd;
Thread serverThread;
byte[] recvData = new byte[10240]; //接收的数据,必须为字节
int recvLen; //接收的数据长度
string recvStr;
// Use this for initialization
int socketCount;
void Start () {
//本机IP和端口
//string address = "192.168.0.113";
//int port = 10001;
//定义服务器的IP和端口,端口与服务器对应
//ip = IPAddress.Parse(address); //可以是局域网或互联网ip,此处是本机
ipEnd = new IPEndPoint(IPAddress.Any, 10001); //服务器端口号
//创建socket连接
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(ipEnd); //绑定IP地址:端口
serverSocket.Listen(10); //设定最多10个排队连接请求
accpetSocket = new Socket[10];
socketCount = 0;
serverThread = new Thread(ListenClientConnect);
serverThread.Start();
}
// Update is called once per frame
void Update () {
}
private void ListenClientConnect()
{
int count = 0;
IPEndPoint clientIpe;
while (true)
{
accpetSocket[count] = serverSocket.Accept();
clientIpe = (IPEndPoint)accpetSocket[count].RemoteEndPoint;
accpetSocket[count].Send(Encoding.Unicode.GetBytes("Hello Clinet " + clientIpe.Address.ToString()));
Thread receiveThread = new Thread(ReceiveMessage);
receiveThread.Start();
count++;
}
}
private void SendMsgToClient()
{
//服务器发送数据部分
for (int i = 0; i < accpetSocket.Length; i++)
accpetSocket[i].Send(Encoding.Unicode.GetBytes("Hello client !!!!!"));
}
private void SendMsgToClient(Socket socket, string msg)
{
socket.Send(Encoding.Unicode.GetBytes(msg));
}
private void ReceiveMessage()
{
Socket socket = accpetSocket[socketCount];
socketCount++;
while (true)
{
try
{
Array.Clear(recvData, 0, recvData.Length);
recvLen = socket.Receive(recvData);
if (recvLen == 0) //连接断开,或者在TCPClient上调用了Close()方法,或者在流上调用了Dispose()方法.
{
break;
}
recvStr = Encoding.Unicode.GetString(recvData);//从二进制转换为字符串对应的客户端会有从字符串转换为二进制的方法
SendMsgToClient(socket, recvStr);
}
catch(Exception ex)
{
break;
}
}
}
Udp客户端:
Socket clientSocket; //服务器端socket
IPAddress ip; //主机ip
IPEndPoint ipEnd;
EndPoint serverEnd;
string recvStr; //接收的字符串
byte[] recvData = new byte[10240]; //接收的数据,必须为字节
int recvLen; //接收的数据长度
Thread connectThread; //连接线程
//初始化
void Start()
{
//本机IP和端口
string address = "192.168.0.113";
int port = 10001;
//定义服务器的IP和端口,端口与服务器对应
ip = IPAddress.Parse(address); //可以是局域网或互联网ip,此处是本机
ipEnd = new IPEndPoint(ip, port); //服务器端口号
serverEnd = (EndPoint)ipEnd;
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//SocketConnet();
//开启一个线程连接,必须的,否则主线程卡死
connectThread = new Thread(new ThreadStart(SocketReceive));
connectThread.Start();
}
void OnGUI()
{
if (GUI.Button(new Rect(50, 100, 100, 50), "发送数据"))
{
SocketSend("hello server i am No 1");
}
GUI.Label(new Rect(250, 100, 300, 100), "接收数据: " + recvStr);
}
public void SocketSend(string msg)//SocketSend(, T instance)
{
byte[] buffer = Encoding.Unicode.GetBytes(msg);//将字符串转化为二进制
//发送
clientSocket.SendTo(buffer, buffer.Length, SocketFlags.None, ipEnd);
}
void SocketReceive()
{
SocketSend("hello server ");
//不断接收服务器发来的数据
while (true)
{
try
{
recvLen = clientSocket.ReceiveFrom(recvData, ref serverEnd);
recvStr = Encoding.Unicode.GetString(recvData, 0, recvLen);
}
catch (Exception ex)
{
return;
}
}
}
Udp服务器:
Socket serverSocket;
IPAddress ipAdress; //主机ip
IPEndPoint ipEnd;
EndPoint clientEnd;
Thread serverThread;
byte[] recvData = new byte[10240]; //接收的数据,必须为字节
string recvStr;
int recvLen;
// Use this for initialization
void Start () {
//本机IP和端口
//string address = "192.168.0.113";
//int port = 10001;
//定义服务器的IP和端口,端口与服务器对应
//ipAdress = IPAddress.Parse(address); //可以是局域网或互联网ip,此处是本机
ipEnd = new IPEndPoint(IPAddress.Any, 10001); //服务器端口号
clientEnd = (EndPoint)ipEnd;
//创建socket连接
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
serverSocket.Bind(ipEnd); //绑定IP地址:端口
serverThread = new Thread(ReceiveMessage);
serverThread.Start();
}
// Update is called once per frame
void Update () {
}
void OnGUI()
{
if (GUI.Button(new Rect(50, 100, 100, 50), "发送数据"))
{
SendMsgToClient();
}
GUI.Label(new Rect(50, 0, 300, 100), "接收数据: " + recvStr);
}
private void SendMsgToClient()
{
//服务器发送数据部分
serverSocket.SendTo(Encoding.Unicode.GetBytes("Hello client !!!!!"), clientEnd);
}
private void SendMsgToClient(EndPoint point, string msg)
{
serverSocket.SendTo(Encoding.Unicode.GetBytes(msg), point);
}
private void ReceiveMessage()
{
while (true)
{
try
{
recvLen = serverSocket.ReceiveFrom(recvData, ref clientEnd);
recvStr = Encoding.Unicode.GetString(recvData, 0, recvLen);//从二进制转换为字符串对应的客户端会有从字符串转换为二进制的方法
SendMsgToClient(clientEnd, recvStr);
}
catch(Exception ex)
{
break;
}
}
}