热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于☀️TCP/IP协议的聊天实例

目录🟥认识Socket🟧创建一个Socket服务器1️⃣服务器端2️⃣Unity端(客户端)🟨

在这里插入图片描述 

目录

🟥 认识Socket

🟧 创建一个Socket服务器

1️⃣ 服务器端

2️⃣ Unity端(客户端)

🟨 创建异步Socket Conn类

🟩 创建异步Socket Sever类

1️⃣ 第一步:添加Server类

2️⃣ 第二步:改Main方法

3️⃣ 第三步:调试

🟦 实战:开发一款多人聊天室



🟥 认识Socket

Skcket:套接字

Socket怎样传输数据?

客户端:

1、链接:connect,连接到服务器Accept

2、写入:write——服务器read    往服务器发送请求/向服务器写入账号密码等

3、读取:read——服务器write    客户端读取服务器发来的请求,根据发来的信息进行下一步操作

4、关闭:close——服务器close    如果一直连接socket,会占用资源

服务端:
1、绑定:Bind

2、监听:Listen

ps:1,2步是先把服务器开启起来进行监听,这样客户端才能访问进来

3、创建一个新的链接:Accept。因为服务器不可能只和一个客户端连接,所以和当前客户端建立一个新的连接,当再来别的客户端连接时,再创建新的链接

4、读取:Read    当收到客户端write请求时,读取数据库是否有该账号密码等,进行数据的验证

5、写入:write    当服务器在数据库读取到数据时,服务器返回/发送请求(查询到信息)给客户端

6、关闭:close

 

 

🟧 创建一个Socket服务器

注:本段是同步

同步和异步的区别:

同步:只能监听一个

异步:可监听多个(真正根据listdfd.Listen(0);  //监听的个数 0代表不限制,同步模式即使这样写也只监听一个)

1️⃣ 服务器端

vs安装:.NET桌面开发

VS新建:控制台应用(.NET Framework)  文件名:mysocket

代码如下:

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;namespace mysocket
{class Program{static void Main(string[] args){Socket listdfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ipAdr = IPAddress.Parse("127.0.0.1"); //服务器地址IPEndPoint ipEp = new IPEndPoint(ipAdr, 1234); //服务器地址+端口号(端口号可随意)listdfd.Bind(ipEp);listdfd.Listen(0); //监听的个数 0代表不限制Console.WriteLine("服务器启动成功");while (true){Socket connfd = listdfd.Accept(); //创建一个新的链接Console.WriteLine("服务器Accept成功");byte[] readbuff = new byte[1024];int count = connfd.Receive(readbuff); //接受客户端信息:有数据发送过来就会接收string str = Encoding.Default.GetString(readbuff, 0, count);Byte[] bytes = Encoding.Default.GetBytes("服务器输出" + str);connfd.Send(bytes);}}}
}

 

 

2️⃣ Unity端(客户端)

build Settings——Resolution and Presentation——Run in background(勾选),允许你的游戏在后台运行。若取消勾选,则切换到后台时,你的游戏将失去响应

创建connect脚本挂载到Camera,代码如下

using UnityEngine;
using System.Net.Sockets;public class connect : MonoBehaviour {Socket socket;const int buff_size = 1024;byte[] readbuff = new byte[buff_size];private void Start(){connection();}public void connection(){socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);string host = "127.0.0.1";int port = 1234;socket.Connect(host, port);print("客户端地址" + socket.LocalEndPoint); //显示客户端连接信息string str = "nihao";byte[] bytes = System.Text.Encoding.Default.GetBytes(str);socket.Send(bytes);int count = socket.Receive(readbuff);str = System.Text.Encoding.Default.GetString(readbuff, 0, count);print(str);socket.Close();}
}

此时,调试VS,启动Unity,观察到以下结果

 

 

🟨 创建异步Socket Conn类

在二基础上,打开服务端,添加Conn类,代码如下

using System;
using System.Net.Sockets;namespace mysocket
{///

/// 处理客户端链接的类/// class Conn{//定义缓冲区public const int buff_size = 1024;//定义服务器public Socket socket;//是否使用public bool isUse = false;public byte[] readBuff = new byte[buff_size];public int buffCount = 0;public Conn(){readBuff = new byte[buff_size];}//初始化public void Init(Socket socket){this.socket = socket;isUse = true;buffCount = 0;}//缓冲所剩余的字节数public int BuffRemain(){return buff_size - buffCount;}//获取客户端地址public string GetAdress(){if (!isUse)return "无法获取地址";return socket.RemoteEndPoint.ToString();}//关闭连接public void Close(){if (!isUse)return;Console.WriteLine(GetAdress() + "与服务器断开连接");socket.Close();isUse = false;}}
}

 

 


🟩 创建异步Socket Sever类

1️⃣ 第一步:添加Server类

在第三基础上,同样在服务器端添加Server类,代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;namespace mysocket
{class Server{//监听嵌套字public Socket listedfd;//客户端连接public Conn[] conns;//最大连接数public int maxConn = 50;//获取连接池,返回负数表示连接失败public int NewIndex(){if (conns == null)return -1; //代表没有连接成功for(int i = 0; i }

 

 

2️⃣ 第二步:改Main方法

将Program的Main()内方法删掉,改为如下异步方法(原内容为同步)

using System;namespace mysocket
{class Program{static void Main(string[] args){Server server = new Server();server.Start("127.0.0.1", 1234);while (true){string str = Console.ReadLine();switch (str){case "quit": //关闭socketreturn;}}}}
}

 

 

3️⃣ 第三步:调试

在Main界面调试,若出现“服务器启动成功”,则代表成功

 

 


🟦 实战:开发一款多人聊天室

基于以上内容,打开Unity的客户端,将connect脚本内容改为如下所示:

using UnityEngine;
using System.Net.Sockets;
using UnityEngine.UI;
using System;public class connect : MonoBehaviour {//服务器地址、服务器端口、聊天输入框public InputField hostInput, portInput,TextInput;//客户端收到的信息public Text connecttext;public Text txtstr; //用于UI显示服务器发送过来的数据public string serverstr; //注:必须为public!服务器发送回来的数据//SocketSocket socket;const int buff_size = 1024;public byte[] readbuff = new byte[buff_size];private void Update(){txtstr.text = serverstr;}//连接服务器,绑定“连接”按钮public void Connection(){txtstr.text = "";socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//开始连接服务器string host = hostInput.text;int port = int.Parse(portInput.text); //转化为intsocket.Connect(host, port);print("客户端地址" + socket.LocalEndPoint); //输出:客户端地址127.0.0.1:54000connecttext.text = socket.LocalEndPoint.ToString();//开始接收数据//public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socket_flags, AsyncCallback callback, object state);socket.BeginReceive(readbuff, 0, buff_size, SocketFlags.None, ReceiveCb, null);}//回调方法void ReceiveCb(IAsyncResult ar){try{//接收数据的大小int count = socket.EndReceive(ar);string str = System.Text.Encoding.Default.GetString(readbuff, 0, count);if (serverstr.Length > 300) serverstr = "";serverstr += str + "\n"; //服务器发送回来的数据(经过加换行处理,且公用放在外面)+=接收数据+ "\n"//继续接收数据socket.BeginReceive(readbuff, 0, buff_size, SocketFlags.None, ReceiveCb, null);}catch(Exception ex){txtstr.text = "连接已经断开" + ex.Message;socket.Close();}}public void Send(){string str = TextInput.text;byte[] bytes = System.Text.Encoding.Default.GetBytes(str);try{socket.Send(bytes);}catch{}}
}

Unity界面如下

现在运行Unity,输入127.0.0.1,端口1234,即可开始通讯

unity发布exe,运行多个exe,可在多个客户端之间进行实时通讯

 

 

 

大家还有什么问题,欢迎在下方留言!


 

在这里插入图片描述


如果你有 技术的问题 或 项目开发

都可以加下方联系方式

和我聊一聊你的故事🧡

 


推荐阅读
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
author-avatar
mobiledu2502872283
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有