Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包

这篇具有很好参考价值的文章主要介绍了Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.TCP相关API介绍与服务端编写

TCP是面向连接的。因此需要创建监听器,监听客户端的连接。当连接成功后,会返回一个TcpClient对象。通过TcpClient可以接收和发送数据。

Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包

VS创建C# .net控制台应用

项目中创建文件夹Net,Net 下添加TCPServer.cs类,用来创建TCPListener和Accept客户端连接,实例化一个TCPServcer放在Main函数执行。Client用来管理每一个客户端的接收发送消息。

namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
            TCPServer tcpServer = new TCPServer();
            tcpServer.Start();

            while(true)
            {
                Console.ReadLine();//监听用户输入,不写这句话运行测试会立刻跳出
            }
        }
    }
}
namespace Server.Net
{
    internal class TCPServer
    {
        TcpListener tcpListener;
        //启动服务器,创建监听器
        public void Start()
        {
            try
            {
                //创建监听器,如果不指定IP会以本机的IP为服务器的IP
                tcpListener = TcpListener.Create(7788);//1-65535
                tcpListener.Start(500);//启动监听,传递最大接收多少客户端连接。

                Console.WriteLine("TCP Server Start");

                //启动服务器后,还要调用接收连接
                Accept();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            
        }

        //监听客户端连接
        //由于内部使用的方法是AcceptTcpClientAsync异步,因此方法也要是async
        //这样就可以通过await的方式等待
        public async void Accept()
        {
            try
            {
                //监听TCP客户端连接的返回的对象
                TcpClient tcpClient = await tcpListener.AcceptTcpClientAsync();
                Console.WriteLine("客户端已连接:" + tcpClient.Client.RemoteEndPoint);//打印IP
                                                                               //使用构建的Client类来缓存这些TcpClient
                Client client = new Client(tcpClient);
                Accept();//继续接受来自客户端的连接即可
            }
            catch (Exception e)
            {
                Console.WriteLine($"Accept:{e.Message}");
                tcpListener.Stop();
            }
        }
    }
}
namespace Server.Net
{
    //每一个客户端都是一个独立的Client
    internal class Client
    {
        TcpClient client;
        public Client(TcpClient tcpClient)
        {
            client = tcpClient;
            Receive();
        }

        //接收消息
        public async void Receive()
        {
            //处于连接状态就持续接收信息。
            while(client.Connected)
            {
                try
                {
                    byte[] buffer = new byte[4096];//存储接收到的数据,定义初始容量,一般不超过4096或1024
                    //把消息存到buffer中,从第几个字节开始存,存多长,,,,,,返回length表示接收到多少数据。
                    int length = await client.GetStream().ReadAsync(buffer, 0, buffer.Length);

                    if(length > 0)//表示有效信息
                    {
                        //$作用是将{}内容当做表达式
                        Console.WriteLine($"接收到的数据长度:{length}");
                        Console.WriteLine($"接收到的数据内容:{Encoding.UTF8.GetString(buffer, 0, length)}");//将byte数组转换为字符串
                    }
                    else
                    {
                        //客户端关闭了
                        client.Close();
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Receive Error:{e.Message}");
                    client.Close();//出现错误断开客户端连接。
                }
            }            
        }

        //发送消息
        public async void Send(byte[] data)
        {
            try
            {
                //数据写入网络数据流中。就是发送
                await client.GetStream().WriteAsync(data, 0, data.Length);
                Console.WriteLine("发送成功! " + $"发送的消息内容:{Encoding.UTF8.GetString(data, 0, data.Length)}");
            }
            catch (Exception e)
            {
                client.Close();//关闭客户端
                Console.WriteLine($"send error:{e.Message}");
            }
        }
    }
}

运行测试

2.实现客户端和服务器的消息收发

编写Unity客户端,Client项目,创建Script/Net/Client.cs

注意收发消息都必须是异步的async,因为不能阻塞我们的程序。

using System;
using UnityEngine;
using System.Net.Sockets;
using System.Text;

public class Client
{
    private static Client instance = new Client();
    public static Client Instance => instance;//单例模式便于调用
    
    private TcpClient client;//跟服务器通信需要调用client
    
    public  void Start()
    {
        client = new TcpClient();
        Connect();
    }
    
    //连接服务器接口
    public async void Connect()
    {
        try
        {
            await client.ConnectAsync("127.0.0.1", 7788);
            Debug.Log("TCP 连接成功");
            Receive();
        }
        catch (Exception e)
        {
            Debug.Log(e.Message);
        }
    }
    
    //接收接口
    public async void Receive()
    {
        while (client.Connected)
        {
            try
            {
                byte[] buff = new byte[4096];
                int length = await client.GetStream().ReadAsync(buff, 0, buff.Length);
                if (length > 0)
                {
                    Debug.Log($"接收到的数据长度:{length}");
                    Debug.Log($"接收到的数据内容:{Encoding.UTF8.GetString(buff, 0, length)}");
                }
                else
                {
                    client.Close();
                }
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
                client.Close();
            }
        }
    }
    
    //发送接口
    public async void Send(byte[] data)
    {
        try
        {
            await client.GetStream().WriteAsync(data, 0, data.Length);
            Debug.Log("发送成功! " + $"发送的消息内容:{Encoding.UTF8.GetString(data, 0, data.Length)}");
        }
        catch (Exception e)
        {
            Debug.Log(e.Message);
            client.Close();
        }
    }
}

Unity创建Scripts/GameManager.cs来启动客户端连接服务器

using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Client.Instance.Start();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            Client.Instance.Send(Encoding.UTF8.GetBytes("login..."));
        }
    }
}
public async void Receive()
{
    //处于连接状态就持续接收信息。
    while(client.Connected)
    {
        try
        {
            byte[] buffer = new byte[4096];//存储接收到的数据,定义初始容量,一般不超过4096或1024
            //把消息存到buffer中,从第几个字节开始存,存多长,,,,,,返回length表示接收到多少数据。
            int length = await client.GetStream().ReadAsync(buffer, 0, buffer.Length);

            if(length > 0)//表示有效信息
            {
                //$作用是将{}内容当做表达式
                Console.WriteLine($"接收到的数据长度:{length}");
                Console.WriteLine($"接收到的数据内容:{Encoding.UTF8.GetString(buffer, 0, length)}");//将byte数组转换为字符串

                Send(Encoding.UTF8.GetBytes("测试返回..."));
            }
            else
            {
                //客户端关闭了
                client.Close();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine($"Receive Error:{e.Message}");
            client.Close();//出现错误断开客户端连接。
        }
    }            
}

启动服务器和客户端显示连接成功,测试收发消息。

Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包

注意接收消息成功之后,如果需要返回给客户端消息,必须要返回给特定的客户端,不能搞错。需要通过ClientManager写一个字典管理所有Client,或者直接在Client里面写一个tempClient

public Client tempClient;//缓存客户端发送消息
public async void Accept()
    {
        try
        {
            //监听TCP客户端连接的返回的对象
            TcpClient tcpClient = await tcpListener.AcceptTcpClientAsync();
            Console.WriteLine("客户端已连接:" + tcpClient.Client.RemoteEndPoint);//打印IP
                                                                           //使用构建的Client类来缓存这些TcpClient
            Client client = new Client(tcpClient);
            tempClient = client;
            Accept();//继续接受来自客户端的连接即可
        }
        catch (Exception e)
        {
            Console.WriteLine($"Accept:{e.Message}");
            tcpListener.Stop();
        }
    }
static void Main(string[] args)
{
    TCPServer tcpServer = new TCPServer();
    tcpServer.Start();

    while(true)
    {
        var str = Console.ReadLine();//监听用户输入,不写这句话运行测试会立刻跳出
        tcpServer.tempClient.Send(Encoding.UTF8.GetBytes($"测试主动发送数据:{str}"));
    }
}
Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包

3.使用LitJSON更好的组织网络数据

Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包

在Server项目的VS中打开NuGet包管理器安装LitJson

Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包

在PM输入Install-Package LitJson -Version 0.18.0

每个包都由其所有者许可给你。NuGet 不负责第三方包,也不授予其许可证。一些包可能包括受其他许可证约束的依赖关系。单击包源(源) URL 可确定任何依赖关系。

程序包管理器控制台主机版本 5.10.0.7240

键入 "get-help NuGet" 可查看所有可用的 NuGet 命令。

PM> Install-Package LitJson -Version 0.18.0


正在尝试收集与目标为“.NETFramework,Version=v4.7.2”的项目“Server”有关的包“LitJson.0.18.0”的依赖项信息
收集依赖项信息花费时间 1.81 sec
正在尝试解析程序包“LitJson.0.18.0”的依赖项,DependencyBehavior 为“Lowest”
解析依赖项信息花费时间 0 ms
正在解析操作以安装程序包“LitJson.0.18.0”
已解析操作以安装程序包“LitJson.0.18.0”
从“nuget.org”检索包“LitJson 0.18.0” 
GET https://api.nuget.org/v3-flatcontainer/litjson/0.18.0/litjson.0.18.0.nupkg
OK https://api.nuget.org/v3-flatcontainer/litjson/0.18.0/litjson.0.18.0.nupkg 137 毫秒
已通过内容哈希 zVK/1iUURxvEZH1eiviFpS8Qbh1fZe926ie18vhHuisVYcNbdVjgG85X8BsGt7WBU5Ka3gZvaQXRX6EsoD2hrw== 从 https://api.nuget.org/v3/index.json 安装 LitJson 0.18.0 。
正在将程序包“LitJson.0.18.0”添加到文件夹“E:\graduate\learn\Unity\NetProject\Server\packages”
已将程序包“LitJson.0.18.0”添加到文件夹“E:\graduate\learn\Unity\NetProject\Server\packages”
已将程序包“LitJson.0.18.0”添加到“packages.config”
已将“LitJson 0.18.0”成功安装到 Server
执行 nuget 操作花费时间 8.44 sec
已用时间: 00:00:11.4081423

创建Helper/JsonHelper.cs

using System.Text;

using LitJson;

namespace Server.Helper
{
internal class JsonHelper
    {
        //Object转换为String
        public static string ToJson(object x)//object C#所有类派生于此,所以C#类及自己创建的类都有ToString()
        {
            string str = JsonMapper.ToJson(x);
            return str;
        }

        //String转换为Object
        public static T ToObject<T>(string x)
        {
            return JsonMapper.ToObject<T>(x);
        }

        public static T ToObject<T>(byte[] b)
        {
            string x = Encoding.UTF8.GetString(b, 0, b.Length);
            return ToObject<T>(x);
        }

        public static string GetTestToString()
        {
            JsonTest jsonTest = new JsonTest();
            jsonTest.id = 1;
            jsonTest.name = "jsonTest";
            return ToJson(jsonTest);
        }
    }

    public class JsonTest
    {
        public int id;
        public string name;
    }
}
while(true)
{
    var str = Console.ReadLine();//监听用户输入,不写这句话运行测试会立刻跳出
    //tcpServer.tempClient.Send(Encoding.UTF8.GetBytes($"测试主动发送数据:{str}"));
    var jsonStr = JsonHelper.GetTestToString();
    tcpServer.tempClient.Send(Encoding.UTF8.GetBytes(jsonStr));
}

运行测试,,目前Unity收到的消息还没有反序列化成原本的Object,因为服务器目前发送的是Json格式的String,Unity收到的也是Json格式的String

Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包

Unity Client项目创建Scripts/Helper/JsonHelper.cs,然后找到\NetProject\Server\packages\LitJson.0.18.0\lib\net45\LitJson.dll复制进Unity的Plugins文件夹,,,,重开一下脚本就重新编译好了,不会报错LitJson缺失的问题了

using System.Text;
using LitJson;
using UnityEngine;

public class JsonHelper
{
    //Object转换为String
    public static string ToJson(object x)//object C#所有类派生于此,所以C#类及自己创建的类都有ToString()
    {
        string str = JsonMapper.ToJson(x);
        return str;
    }

    //String转换为Object
    public static T ToObject<T>(string x)
    {
        return JsonMapper.ToObject<T>(x);
    }

    public static T ToObject<T>(byte[] b)
    {
        string x = Encoding.UTF8.GetString(b, 0, b.Length);
        return ToObject<T>(x);
    }

    public static string GetTestToString()
    {
        JsonTest jsonTest = new JsonTest();
        jsonTest.id = 1;
        jsonTest.name = "jsonTest";
        var jsonStr = ToJson(jsonTest);

        var jsonTestObj = ToObject<JsonTest>(ToJson(jsonTest));
        Debug.Log($"{jsonTestObj.id}   /  {jsonTestObj.name}");
        return jsonStr;
    }
    
    public class JsonTest
    {
        public int id;
        public string name;
    }
}
//接收接口
public async void Receive()
{
    while (client.Connected)
    {
        try
        {
            byte[] buff = new byte[4096];
            int length = await client.GetStream().ReadAsync(buff, 0, buff.Length);
            if (length > 0)
            {
                Debug.Log($"接收到的数据长度:{length}");
                Debug.Log($"接收到的数据内容:{Encoding.UTF8.GetString(buff, 0, length)}");
                var jsonTest = JsonHelper.ToObject<JsonHelper.JsonTest>(Encoding.UTF8.GetString(buff, 0, length));
                Debug.Log(jsonTest.id + " " + jsonTest.name);
            }
            else
            {
                client.Close();
            }
        }
        catch (Exception e)
        {
            Debug.Log(e.Message);
            client.Close();
        }
    }
}
Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包

4.粘包和拆包处理

Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包

粘包是因为计算机底层将多条小的数据合并成一条大的发送给另一端,减少网络传输的基本开销,需要拆包将多条数据拆分

用4个字节表示包体大小和消息ID,包体内容可能是账号、密码、业务所需要用到的数据(邮箱、移动(方向轴 目标点))

接收到消息看长度是单条消息没接收完还是一下粘包接受了多条消息。

先看Server端的Client

internal class Client
{
    TcpClient client;
    public Client(TcpClient tcpClient)
    {
        client = tcpClient;
        Receive();
    }

    byte[] data = new byte[4096];//接收消息的缓冲区
    int msgLength = 0;//接收到的消息长度

    //接收消息
    public async void Receive()
    {
        //处于连接状态就持续接收信息。
        while(client.Connected)
        {
            try
            {
                byte[] buffer = new byte[4096];//存储接收到的数据,定义初始容量,一般不超过4096或1024
                //把消息存到buffer中,从第几个字节开始存,存多长,,,,,,返回length表示接收到多少数据。
                int length = await client.GetStream().ReadAsync(buffer, 0, buffer.Length);

                if(length > 0)//表示有效信息
                {
                    //$作用是将{}内容当做表达式
                    Console.WriteLine($"接收到的数据长度:{length}");
                    Console.WriteLine($"接收到的数据内容:{Encoding.UTF8.GetString(buffer, 0, length)}");//将byte数组转换为字符串
                    //Send(Encoding.UTF8.GetBytes("测试返回..."));                    
                    Array.Copy(buffer, 0, data, msgLength, length);//把接收到length长度的消息复制到数据缓冲区中msgLength索引后的位置
                    msgLength += length;//每次收到网络数据都要加上数据的长度
                    Handle();
                }
                else
                {
                    //客户端关闭了
                    client.Close();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"Receive Error:{e.Message}");
                client.Close();//出现错误断开客户端连接。
            }
        }            
    }

    private void Handle()
    {
        //包体大小(4) 协议ID(4) 包体(byte[])
        if (msgLength >= 8)
        {
            byte[] _size = new byte[4];
            Array.Copy(data, 0, _size, 0, 4);//把包体大小从第0位缓存4位长度
            int size = BitConverter.ToInt32(_size, 0);//获得包体大小

            //本次要拿的长度
            var _length = 8 + size;//实际完整消息的长度:包体大小(4)+协议ID(4)+包体(byte[])

            if (msgLength>=_length)//判断数据缓冲区的长度是否大于一条完整消息的长度。
            {
                //拿出id
                byte[] _id = new byte[4];
                Array.Copy(data, 4, _id, 0, 4);//把协议ID从第4位缓存4位长度
                int id = BitConverter.ToInt32(_id, 0);//获得协议ID

                //包体
                byte[] body = new byte[size];
                Array.Copy(data, 8, body, 0, size);//把包体从第8位缓存size位长度

                if (msgLength>_length)//如果接收到的数据长度大于这次取出的完整一条数据的长度,说明还有数据
                {
                    for (int i = 0; i < msgLength - _length; i++)
                    {
                        data[i] = data[_length + i];//前面取完一次完整消息了,把后面的消息前挪
                    }
                }
                msgLength -= _length;//减掉已经取完的消息长度
                Console.WriteLine($"收到客户端请求:{id}");
                //根据id进行处理,,实际项目一般使用观察者模式,监听id和Action事件绑定
                switch (id)
                {
                    case 1001://注册请求
                        RegisterMsgHandle(body);
                        break;
                    case 1002://登录业务
                        LoginMsgHandle(body);
                        break;
                    case 1003://聊天业务
                        ChatMsgHandle(body);
                        break;

                }
            }
        }
    }

    //处理注册请求
    private void RegisterMsgHandle(byte[] obj)
    {
        
    }

    //处理登录请求
    private void LoginMsgHandle(byte[] obj)
    {

    }

    //处理聊天请求
    private void ChatMsgHandle(byte[] obj)
    {

    }

    //发送消息
    public async void Send(byte[] data)
    {
        try
        {
            //数据写入网络数据流中。就是发送
            await client.GetStream().WriteAsync(data, 0, data.Length);
            Console.WriteLine("发送成功! " + $"发送的消息内容:{Encoding.UTF8.GetString(data, 0, data.Length)}");
        }
        catch (Exception e)
        {
            client.Close();//关闭客户端
            Console.WriteLine($"send error:{e.Message}");
        }
    }
}

根据id进行处理,,实际项目一般使用观察者模式,监听id和Action事件绑定

Unity客户端添加Scritps/Helper/MessageHelper.cs脚本

public class MessageHelper
{
    private static MessageHelper instance = new MessageHelper();
    public static MessageHelper Instance => instance;//单例
    
    byte[] data = new byte[4096];//接收消息的缓冲区
    int msgLength = 0;//接收到的消息长度

    //client接收到消息时,把buffer的数据复制到data数据缓冲区,数据长度加上接受的新有效数据流长度,handle处理数据
    public void CopyToData(byte[] buffer, int length)
    {
        Array.Copy(buffer, 0, data, msgLength, length);
        msgLength += length;
        Handle();
    }
    
    private void Handle()
    {
        //包体大小(4) 协议ID(4) 包体(byte[])
        if (msgLength >= 8)
        {
            byte[] _size = new byte[4];
            Array.Copy(data, 0, _size, 0, 4);//把包体大小从第0位缓存4位长度
            int size = BitConverter.ToInt32(_size, 0);//获得包体大小

            //本次要拿的长度
            var _length = 8 + size;//实际完整消息的长度:包体大小(4)+协议ID(4)+包体(byte[])

            if (msgLength>=_length)//判断数据缓冲区的长度是否大于一条完整消息的长度。
            {
                //拿出id
                byte[] _id = new byte[4];
                Array.Copy(data, 4, _id, 0, 4);//把协议ID从第4位缓存4位长度
                int id = BitConverter.ToInt32(_id, 0);//获得协议ID

                //包体
                byte[] body = new byte[size];
                Array.Copy(data, 8, body, 0, size);//把包体从第8位缓存size位长度

                if (msgLength>_length)//如果接收到的数据长度大于这次取出的完整一条数据的长度,说明还有数据
                {
                    for (int i = 0; i < msgLength - _length; i++)
                    {
                        data[i] = data[_length + i];//前面取完一次完整消息了,把后面的消息前挪
                    }
                }
                msgLength -= _length;//减掉已经取完的消息长度
                Debug.Log($"收到客户端请求:{id}");
                //根据id进行处理,,实际项目一般使用观察者模式,监听id和Action事件绑定
                switch (id)
                {
                    case 1001://注册请求
                        RigisterMsgHandle(body);
                        break;
                    case 1002://登录业务
                        LoginMsgHandle(body);
                        break;
                    case 1003://聊天业务
                        ChatMsgHandle(body);
                        break;

                }
            }
        }
    }

    //按格式封装消息,发送到服务器
    public void SendToServer(int id, string str)
    {
        Debug.Log("ID:" + id);
        var body = Encoding.UTF8.GetBytes(str);
        byte[] send_buff = new byte[body.Length + 8];

        int size = body.Length;

        var _size = BitConverter.GetBytes(size);
        var _id = BitConverter.GetBytes(id);

        Array.Copy(_size, 0, send_buff, 0, 4);
        Array.Copy(_id, 0, send_buff, 4, 4);
        Array.Copy(body, 0, send_buff, 8, body.Length);

        Client.Instance.Send(send_buff);
    }
    
    //处理注册(结果)请求
    private void RigisterMsgHandle(byte[] obj)
    {
            
    }

    //处理登录(结果)请求
    private void LoginMsgHandle(byte[] obj)
    {

    }

    //处理聊天(转发)请求
    private void ChatMsgHandle(byte[] obj)
    {

    }
}
public async void Receive()
{
    while (client.Connected)
    {
        try
        {
            byte[] buff = new byte[4096];
            int length = await client.GetStream().ReadAsync(buff, 0, buff.Length);
            if (length > 0)
            {
                Debug.Log($"接收到的数据长度:{length}");
                //接收到处理CopyToData给MessageHelper处理信息
                MessageHelper.Instance.CopyToData(buff, length);
            }
            else
            {
                client.Close();
            }
        }
        catch (Exception e)
        {
            Debug.Log(e.Message);
            client.Close();
        }
    }
}

发送消息的时候必须按照格式发送文章来源地址https://www.toymoban.com/news/detail-470562.html

//按格式封装后,发送消息
public void SendToClient(int id, string str)
{
    //包体转换为byte[]
    var body = Encoding.UTF8.GetBytes(str);

    //包体大小(4) 协议ID(4) 包体内容
    byte[] send_buff = new byte[body.Length + 8];

    int size = body.Length;
    var _size = BitConverter.GetBytes(size);
    var _id = BitConverter.GetBytes(id);

    Array.Copy(_size, 0, send_buff, 0, 4);
    Array.Copy(_id, 0, send_buff, 4, 4);
    Array.Copy(body, 0, send_buff, 8, body.Length);

    Send(send_buff);
}

到了这里,关于Unity-TCP-网络聊天功能(一): API、客户端服务器、数据格式、粘包拆包的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 计算机网络 TCP/UDP程序开发网络聊天室

    计算机网络 TCP/UDP程序开发网络聊天室

    TCP/UDP程序开发 开发TCP/UDP协议应用程序,掌握网络应用程序的工作原理。通过该实验,深入理解UDP和TCP协议的异同点,了解网络协议的工作过程,学会网络通信编程的基本方法,能够编制网络应用程序。 (1)了解和掌握“基于UDP-面向无连接的应用程序/基于TCP-面向连接的

    2024年02月05日
    浏览(7)
  • 网络编程 IO多路复用 [select版] (TCP网络聊天室)

    网络编程 IO多路复用 [select版] (TCP网络聊天室)

    //head.h                 头文件 //TcpGrpSer.c        服务器端 //TcpGrpUsr.c        客户端 select函数  功能:阻塞函数,让内核去监测集合中的文件描述符是否准备就绪,若准备就绪则解除阻塞。 原型: head.h TcpGrpSer.c TcpGrpUsr.c    

    2024年02月14日
    浏览(11)
  • 网络编程 IO多路复用 [epoll版] (TCP网络聊天室)

    网络编程 IO多路复用 [epoll版] (TCP网络聊天室)

    //head.h            头文件 //TcpGrpSer.c     服务器端 //TcpGrpUsr.c     客户端 通过IO多路复用实现服务器在单进程单线程下可以与多个客户端交互  API epoll函数  head.h TcpGrpSer.c TcpGrpUsr.c  

    2024年02月11日
    浏览(14)
  • Linux socket网络编程实战(tcp)实现双方聊天

    Linux socket网络编程实战(tcp)实现双方聊天

    在上节已经系统介绍了大致的流程和相关的API,这节就开始写代码! 回顾上节的流程: 创建一个NET文件夹 来存放网络编程相关的代码: 这部分先实现服务器的连接部分的代码并进行验证 server1.c: 代码验证: 先编译并运行这部分代码: 可见,此时没有客户端进行连接,程

    2024年02月03日
    浏览(11)
  • QT C++ 基于TCP通信的网络聊天室

    QT C++ 基于TCP通信的网络聊天室

    .ui .pro 在pro文件中添加network库 .h .main .cpp .ui .pro 在pro文件中添加network库 .h .main .cpp        

    2024年02月09日
    浏览(10)
  • [Socket]Python用UDP协议建立带有私聊功能的网络聊天室-建立聊天工具

    [Socket]Python用UDP协议建立带有私聊功能的网络聊天室-建立聊天工具

    前些天实习面试的时候被面试官问到Socket编程的问题,即“Socket创建和释放的具体过程是什么”,当时答不上来,似乎是涉及到发送和接收缓冲区的问题。由于自己在Socket编程这一块知识较为薄弱,于是写下这篇文章,当作复习下Socket编程知识。 首先,该实验是我在大三上学

    2024年02月03日
    浏览(9)
  • 多人聊天室(带私聊功能)Linux网络编程基础

    多人聊天室(带私聊功能)Linux网络编程基础

    在和同学一起努力下终于完成了期末作业哈哈哈哈 文章目录 目录 前言 一、需求分析 二、功能设计 1.服务器端: 2.客户端: 三、流程图: 编程流程图: 服务器流程图: 客户端流程图: 四、运行效果: 项目源码: 服务器源码 客户端源码: 总结: Linux网络编程是我们这学

    2024年02月09日
    浏览(11)
  • Java网络编程(二)NIO和Netty实现多人聊天功能
  • 09-微信小程序 网络请求API(实现轮播广告和简易的聊天窗口)

    09-微信小程序 网络请求API(实现轮播广告和简易的聊天窗口)

    09-微信小程序API网络请求(实现轮播广告和简易的聊天窗口) 做项目的开发,一定离不开网络相关的操作,小程序做的都是客户端,客户端请求服务端做一些交互。 微信小程序提供的API的方式,通过API的方式可以调用微信提供的强大的功能,以增强小程序的功能,如:网络请

    2024年02月11日
    浏览(9)
  • Week 08-day02-Unity网络通讯之聊天室

    Week 08-day02-Unity网络通讯之聊天室

    简单UI拖拽一下:  聊天室实现步骤: 1.向服务器发送消息 2.刷新Content聊天界面 3.清空输入框  代码: chatPanel: NetManager: 加上服务器运行截图: 代码: 动态链接库:ProtocolConfig: 动态链接库:ProtocolEnum: 动态链接库:SocketMessage: Main函数: NetManager: ClientPeer类: ClientMessage类:

    2024年02月06日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包