unity使用socket编程实现聊天室功能

作者:九本才 时间:2023-10-18 05:26:04 

本文实例为大家分享了unity使用socket实现聊天室功能的具体代码,供大家参考,具体内容如下

示例:

unity使用socket编程实现聊天室功能

什么是Socket:

Socket(套接字),用来描述IP地址和端口,是通信链的句柄,应用程序可以通过Socket向网络发送请求或者应答网络请求!Socket是支撑TCP/IP协议的网络通信的基本操作单元,是对网络通信过程中端点的抽象表示,包含了进行网络通信所必须的五种信息:连接使用的协议,本地主机的IP地址,本地远程的协议端口,远地主机的IP地址,远地进程的协议端口。

通信模型:

unity使用socket编程实现聊天室功能

服务端实现连接的步骤

1.创建Socket,绑定IP和端口。

2.调用Accept()监听客户端请求。

3.简历连接后,通过输入流读取客户端发送的请求。

4.通过输出流向客户端发送信息。

5.关闭相关资源。

客户端实现连接的步骤

1.创建Socket,指明需要连接的服务器地址和端口号。

2.建立连接后向服务器发送请求。

3.相应服务器信息。

4.关闭相关资源。

基本操作:


public Socket (System.Net.Sockets.AddressFamily addressFamily,
              System.Net.Sockets.SocketType socketType,
              System.Net.Sockets.ProtocolType protocolType);

创建一个Socket调用他的构造函数;

addressFamily参数指定类使用的寻址方案Socket

socketType参数指定类的类型 Socket

protocolType 参数指定所使用的协议Socket

这三个参数不是独立的。 某些地址族限制可与它们一起使用的协议,而类型通常Socket是协议中的隐式。 如果地址族、 Socket类型和协议类型的组合导致无效 Socket ,则此构造函数会引发 SocketException。

Bind()

如果需要使用特定的本地终结点,请使用方法。 必须先调用, Bind然后才能调用Listen()方法。

在调用之前 ,必须先创建 IPEndPoint 用于与数据通信的本地。

Listen()Connect()

将Socket置于侦听状态。Listen导致面向连接的Socket监听传入的连接尝试。 backlog参数指定可以排队等待接受的传入连接的数量。

Connect与远程主机建立连接。

Accept()

为新建连接创建新的Socket。Accept从侦听套接字的连接请求队列中同步提取第一个挂起的连接请求,然后创建并返回一个新的Socket。

Receive()

接收来自绑定的Socket的数据。Receive方法将数据读入 buffer 参数,并返回成功读取的字节数。

Send()

将数据发送到连接的Socket。Send将数据同步发送到或方法中指定的远程主机并返回成功发送的字节数。

Poll()

确定 Socket 的状态。microSeconds等待响应的时间(以微秒为单位)。基于 mode 参数中传递的轮询模式值的 Socket 的状态。

Close()

关闭 Socket 连接并释放所有关联的资源。

使用Socket创建一个简单的聊天室

服务端

写了一控制台应用,也可以移植到其他平台。


using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace MyServer
{
   class Client
   {
       private Socket clientSocket;
       private Thread t;
       private byte[] data = new byte[1024];
       public Client(Socket s)
       {
           clientSocket = s;
           //启动一个线程接受数据;
           t = new Thread(ReceiveMessage);
           t.Start();

}
       private void ReceiveMessage()
       {
           while (true)
           {
               //判断连接是否断开

if (clientSocket.Poll(10, SelectMode.SelectRead))
                   {
                   clientSocket.Close();
                       break;//跳出循环

}

int length = clientSocket.Receive(data);
               string message = Encoding.UTF8.GetString(data, 0, length);
               //接受到数据要分发到客户端
               Console.WriteLine("收到:" + message);
               Program.BroadcastMessage(message);
           }
       }
       public void SendMessage(string message)
       {
           byte[] data = Encoding.UTF8.GetBytes(message);
           clientSocket.Send(data);
       }
       public bool Connected
       {
           get { return clientSocket.Connected; }
       }
   }

class Program
   {
       //存储每一个客户端
       static List<Client> clientList = new List<Client>();

/// <summary>
       /// 服务器广播这个消息
       /// </summary>
       /// <param name="message"></param>
       public static void BroadcastMessage(string message)
       {
           var notConnectedList = new List<Client>();

foreach (var client in clientList)
           {
               if (client.Connected)
                   client.SendMessage(message);
               else
                   notConnectedList.Add(client);
           }
           foreach (var item in notConnectedList)
           {
               clientList.Remove(item);
           }
       }

static void Main(string[] args)
       {

Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
           //192.168.xx.xxx
           tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.xx.xxx"), 7788));
           tcpServer.Listen(100);

Console.WriteLine("服务器启动成功");

while (true)
           {
               Socket clientSocket = tcpServer.Accept();
               Console.WriteLine("有一个客户端连过来了");
               Client client = new Client(clientSocket);//收发消息放到Client类中处理
               clientList.Add(client);
           }

}
   }
}

客户端

使用Unity编写的客户端


using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using UnityEngine;
using System.Net;
using UnityEngine.UI;
using System.Text;
using System.Threading;

public class MyClient : MonoBehaviour
{
   public string ipaddress = "192.168.xx.xxx";
   public int port=7788;

private Socket clientSocket;

private Thread t;

private byte[] data = new byte[1024];
   public InputField inputField;
   public Text chat;
   public InputField myName;
   public string message = "";
   void Start()
   {
       ConnectToServer();
   }
   private void Update()
   {
       if (message != null && message !="")
       {
           chat.text += "\n" + message;
           message = "";
       }
   }
   private void ConnectToServer()
   {
       clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
       //发起连接
       clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress), port));
       //创建一个新的线程接受消息
       t = new Thread(ReceiveMessage);
       t.Start();

}
  //循环接受消息
   void ReceiveMessage()
   {

while (true)
       {
           if (clientSocket.Connected == false)
               break;
           int length = clientSocket.Receive(data);

message = Encoding.UTF8.GetString(data, 0, length);

//  chat.text += "\n" + message;
       }

}
   void SendMessages(string message)
   {
       byte[] data = Encoding.UTF8.GetBytes(message);
       clientSocket.Send(data);
   }

public void OnSendButtonClick()
   {
       string value = myName.text+":"+ inputField.text;
       SendMessages(value);
       inputField.text = "";
   }

private void OnDestroy()
   {
       t.Abort();
       clientSocket.Shutdown(SocketShutdown.Both);//既不接受也不发送
       clientSocket.Close();//关闭连接
   }
}

来源:https://blog.csdn.net/f402455894/article/details/121354628

标签:unity,socket,聊天室
0
投稿

猜你喜欢

  • Android自定义UI手势密码终结版

    2021-07-29 15:40:17
  • C#内置队列类Queue用法实例

    2023-07-18 14:12:05
  • spring AOP的Around增强实现方法分析

    2021-10-03 06:22:39
  • 探讨Java中函数是值传递还是引用传递问题

    2021-07-25 19:34:44
  • Kotlin协程launch原理详解

    2023-05-19 09:36:01
  • 详解C#如何优雅地终止线程

    2023-11-21 11:41:31
  • Android串口通信apk源码详解(附完整源码)

    2021-06-07 04:39:05
  • 详解Java图形化编程中的鼠标事件设计

    2022-07-11 08:11:31
  • Android中仿IOS提示框的实现方法

    2023-01-06 15:47:07
  • C语言转义字符实例详解

    2021-08-23 02:12:20
  • 微信开发之使用java获取签名signature

    2022-08-01 10:47:01
  • 详解关于java文件下载文件名乱码问题解决方案

    2021-07-05 15:27:04
  • Java比较两个List的值是否相等的方法

    2022-12-31 15:41:37
  • C#获取路由器外网IP,MAC地址的实现代码

    2021-07-03 06:01:32
  • SpringBoot项目中如何访问HTML页面

    2021-08-09 11:19:07
  • 详解C#如何加密解密RAR文件

    2023-09-19 16:25:10
  • Android开发升级AGP7.0后的一些适配方法技巧

    2022-10-22 17:41:22
  • 详解Java使用Jsch与sftp服务器实现ssh免密登录

    2023-11-24 18:34:18
  • java实现钉钉机器人消息推送的示例代码

    2023-05-18 13:53:25
  • Android自定义控件实现边缘凹凸的卡劵效果

    2022-10-01 01:20:51
  • asp之家 软件编程 m.aspxhome.com