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

开发笔记:Socket之简单的Unity3D聊天室__TCP协议

本文由编程笔记#小编为大家整理,主要介绍了Socket之简单的Unity3D聊天室__TCP协议相关的知识,希望对你有一定的参考价值。 服务器端程序 1 using System; 2 using S
本文由编程笔记#小编为大家整理,主要介绍了Socket之简单的Unity3D聊天室__TCP协议相关的知识,希望对你有一定的参考价值。


服务器端程序


技术分享图片技术分享图片

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Net.Sockets;
6 using System.Text;
7 using System.Threading.Tasks;
8 namespace 聊天室_服务器端_TCP
9 {
10 class Program
11 {
12 //存放客户端
13 static List clientList = new List();
14
15 //广播消息
16 public static void BroadCastMessage(string message)
17 {
18 //创建未连接的list
19 var notCOnnectedList= new List();
20 foreach(Client client in clientList)
21 {
22 if (client.Connected) //给所有连接的客户端发送消息;
23 client.SendMessage(message);
24 else //把未连接的客户端加入list
25 {
26 notConnectedList.Add(client);
27 }
28 }
29 //移除未连接的客户端
30 foreach(var temp in notConnectedList)
31 {
32 clientList.Remove(temp);
33 }
34 }
35
36 static void Main(string[] args)
37 {
38 //实例化服务器端Socket并指定IP地址类型(IPV4),套接字类型(流类型),通信协议(TCP)
39 Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
40
41 //绑定终端(设置IP地址,端口号(范围为0-65535之间随意取,为避免端口号已被其他软件占用,可以取大点))
42 tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.107"), 7788));
43
44 //开始监听,等待客户端接入,接入后执行后续操作
45 tcpServer.Listen(100);
46 Console.WriteLine("开始监听");
47
48 //循环等待客户端接入
49 while (true)
50 {
51
52 Socket ClientSocket = tcpServer.Accept();
53 Console.WriteLine("一个客户端连接进来了");
54 Client client = new Client(ClientSocket);
55 clientList.Add(client);
56 }
57
58 }
59 }
60 }


Main

技术分享图片技术分享图片

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net.Sockets;
5 using System.Text;
6 using System.Threading;
7 using System.Threading.Tasks;
8
9 namespace 聊天室_服务器端_TCP
10 {
11 public class Client
12 {
13 private Socket clientsocket;
14 private Thread t; //线程
15 private byte[] data = new byte[1024];
16 public Client(Socket s)
17 {
18 this.clientsocket = s;
19
20 //启动一个线程,处理客户端数据接收
21 t = new Thread(ReceiveMessage);
22 t.Start();
23 }
24
25 private void ReceiveMessage()
26 {
27 //一直接收客户端数据
28 while(true)
29 {
30 if(clientsocket.Poll(10,SelectMode.SelectRead))
31 {
32 clientsocket.Close();
33 break;
34 }
35 int length= clientsocket.Receive(data);
36 string message = Encoding.UTF8.GetString(data, 0, length);
37 //接收到数据时,要把这个数据分发到客户端
38 //广播消息
39 Program.BroadCastMessage(message);
40 Console.WriteLine("收到消息:" + message);
41 }
42 }
43
44 //发送消息给客户端
45 public void SendMessage(string message)
46 {
47 byte[] data = Encoding.UTF8.GetBytes(message);
48 clientsocket.Send(data);
49 }
50
51 //判断是否连接
52 public bool Connected
53 {
54 get { return clientsocket.Connected; }
55 }
56 }
57 }


Client类

 

客户端


技术分享图片技术分享图片

1 using System.Collections;
2 using System.Collections.Generic;
3 using System.Net.Sockets;
4 using UnityEngine;
5 using System.Net;
6 using System.Text;
7 using UnityEngine.UI;
8 using System.Threading;
9
10 public class ChatManger : MonoBehaviour {
11
12 public string ipaddress = "192.168.0.107";
13 public int port = 7788;
14 public Text Input; //InputField中显示输入的text
15 public Text Label; //聊天室显示的text
16
17 private Socket client_socket;
18 private Thread t;
19 private byte[] data = new byte[1024]; //数据容器
20 private string message = ""; //消息容器
21 // Use this for initialization
22 void Start () {
23 OnConnectedToServer();
24 }
25
26 // Update is called once per frame
27 void Update () {
28 if(message!=""&&message!=null)
29 {
30 Label.text += "
" + message;
31 message = "";
32 }
33 }
34
35 //连接至服务器,并创建一个新线程用于接受消息
36 public void OnConnectedToServer()
37 {
38 client_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
39 client_socket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress),port));
40
41 t = new Thread(ReceiveMessage);
42 t.Start();
43 }
44
45 //接收消息
46 public void ReceiveMessage()
47 {
48 while(true)
49 {
50 if (client_socket.Poll(10, SelectMode.SelectRead))
51 {
52 client_socket.Close();
53 break;
54 }
55 int length = client_socket.Receive(data);
56 message = Encoding.UTF8.GetString(data, 0, length);
57 //Label.text += "
" + message; unity不允许在单独的线程里去操控其组件

58 }
59 }
60 //发送消息
61 public new void SendMessage(string message)
62 {
63 byte[] data = Encoding.UTF8.GetBytes(message);
64 client_socket.Send(data);
65 }
66 //点击发送按钮
67 public void OnSendButtonClick()
68 {
69
70 SendMessage(Input.text);
71 Input.GetComponentInParent().text = "";
72 }
73
74 //当Mono被销毁时调用此方法
75 private void OnDestroy()
76 {
77 client_socket.Shutdown(SocketShutdown.Both);
78 client_socket.Close();
79 }
80 }


客户端代码

技术分享图片

 


推荐阅读
  • python网络编程 day27 网络编程初识 ——socket
    一、内容回顾1、两个内置函数(装饰器)及类中的魔术方法 ... [详细]
  • iwanttowriteasimpleAppforme(Android).Forthisitisnecessarythattheservercansenddat ... [详细]
  • 并不是上一个用SocketServer的聊天室的延续。用远程调用完成的聊天室。正好有Java的RMI聊天室的作业,就先用Python写了一个简单的类似远程调用的东西& ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 本文介绍了在实现了System.Collections.Generic.IDictionary接口的泛型字典类中如何使用foreach循环来枚举字典中的键值对。同时还讨论了非泛型字典类和泛型字典类在foreach循环中使用的不同类型,以及使用KeyValuePair类型在foreach循环中枚举泛型字典类的优势。阅读本文可以帮助您更好地理解泛型字典类的使用和性能优化。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • ZooKeeper 学习
    前言相信大家对ZooKeeper应该不算陌生。但是你真的了解ZooKeeper是个什么东西吗?如果别人面试官让你给他讲讲ZooKeeper是个什么东西, ... [详细]
  • 浅谈Java8 的foreach跳出循环break/return_java
    这篇文章主要介绍了Java8的foreach跳出循环breakreturn,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完 ... [详细]
  • 嵌套函数定义时先判断function_exists防止递归调用外部函数导致两次定义内部函数导致致命错误看一下PHP手册中是如何说的: ... [详细]
  • Abp+MongoDb改造默认的审计日志存储位置
    一、背景在实际项目的开发当中,使用AbpZero自带的审计日志功能写入效率比较低。其次审计日志数据量中后期十分庞大,不适合与业务数据存放在一起。所以我们可以重新实现A ... [详细]
  • Docker 快速入门指引
    本文最早发表于本人博客:Docker快速入门指引Docker是什么?Docker是Docker.Inc公司开源的一个基于LXC技术之上构建的Container容器引擎,基于Go语言 ... [详细]
author-avatar
timer_open
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有