C# Socket类实现TCP/IP通信客户端

本文详细介绍了如何在C#Unity中使用Socket类创建一个TCP/IP客户端,连接到服务器并实现数据传输。同时展示了服务端的代码实现,包括监听连接、接收和发送数据的过程。
摘要由CSDN通过智能技术生成

在本文中(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; //给文本赋上服务端传过来的消息
        }
    }
}

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我不食卷心菜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值