在本文中(c# Unity),我们将学习如何使用C#编写一个基本的TCP/IP客户端,以便在计算机之间进行通信。Socket是C#中用于网络通信的基本类之一,它允许应用程序在本地计算机和远程计算机之间进行通信。在本文中,我们将使用Socket类来创建一个TCP/IP客户端应用程序,以便可以从本地计算机向远程计算机发送数据。
TCP/IP,即传输控制协议/网际协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议,同时也是一种应用广泛的网络协议。
TCP/IP协议包含了两个主要的协议:传输控制协议(TCP)和网际协议(IP)。
TCP(Transmission Control Protocol):传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。它负责在数据发送和接收设备之间建立连接,确保数据的有序传输,并检查数据在传输过程中是否出错。
IP(Internet Protocol):网际协议是用于发送和接收数据包的协议。每个使用TCP/IP的设备都有一个独一无二的IP地址,这使得数据能够被正确地发送到目标设备。
TCP/IP协议是互
联网的基础,所有的互联网数据通信都是基于TCP/IP协议进行的。
服务端
下面是代码实现 首先要运行服务端 让服务端可以访问网络
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Net.Sockets;
using System.Net;
namespace demo02 //服务端
{
internal class Program
{
//其他线程要使用所以要全局
static Socket socket;
static void Main(string[] args)
{
//得有手机(使用ivp4查找地址,使用字节流传输数据,使用Tcp协议传输)
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//创建手机卡(默认IP地址,自定义端口号)
IPEndPoint ip = new IPEndPoint(IPAddress.Any, 12345);
//绑定手机号
socket.Bind(ip);
//设定接听上线
socket.Listen(10);
//等待别人打电话(会阻塞线程)
//子线程被输入阻塞的时候,主线程能继续正常运行
ThreadPool.QueueUserWorkItem(Accept);
while (true)
{
}
}
private static void Accept(object? state)//等待别人连接(会阻塞线程)
{
Socket client = socket.Accept();
//来电显示
//获取ip地址和端口号
IPEndPoint clientIP = client.RemoteEndPoint as IPEndPoint;
Console.WriteLine(clientIP.Address + ":" + clientIP.Port + "链接");
ThreadPool.QueueUserWorkItem(Receive, client);
//等待下一个连接
ThreadPool.QueueUserWorkItem(Accept);
}
private static void Receive(object? state)
{
Socket client = state as Socket;
//创建一个字节流用来接收消息
byte[] buffer = new byte[1024];
//接收客户端发来的消息(会阻塞线程)
int len=client.Receive(buffer,SocketFlags.None);
//收到长度为0的消息时断开连接
if (len <= 0)
{
//禁止收发消息
client.Shutdown(SocketShutdown.Both);
//关闭连接释放资源
client.Close();
return;
}
//1024是流的长度 len是消息实际长度
byte[] data=buffer.Take(len).ToArray();
//解析data
//byte数组转string
string str=UTF8Encoding.UTF8.GetString(data);
Console.WriteLine(str);
//byte数组转int
//int num=BitConverter.ToInt32(data,0);
//给客户端回消息
Send(client,UTF8Encoding.UTF8.GetBytes("服务端发的消息"));
//开线程收消息
ThreadPool.QueueUserWorkItem(Receive,client);
}
public static void Send(Socket client, byte[] data)
{
client.Send(data);
}
}
客户端
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using UnityEngine;
public class NetManager : MonoBehaviour //客户端
{
public Text text; //unity上的文本
Socket socket;
Queue<byte[]> que=new Queue<byte[]>();
// Start is called before the first frame update
void Start()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect("10.161.54.15", 12345);
//收消息
ThreadPool.QueueUserWorkItem(Receive);
}
private void Receive(object state)
{
byte[] buffer=new byte[1024];
int len=socket.Receive(buffer,SocketFlags.None);
if (len <= 0)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
return;
}
byte[] data=buffer.Take(len).ToArray();
//unity封住了多线程的调用,所以存入队列在主线程调用
que.Enqueue(data);
ThreadPool.QueueUserWorkItem(Receive);
}
// Update is called once per frame
void Update()
{
//在主线程中取出队列的消息
while (que.Count > 0)
{
byte[] data = que.Dequeue();
string str=UTF8Encoding.UTF8.GetString(data);
text.text = str; //给文本赋上服务端传过来的消息
}
}
}