上面我们创建了tcp的客户端和服务端,但是只能进行消息的一次收发。这次我们做一个unity的简易聊天室,使用了线程,可以使用多个客户端连接服务器,并且一个客户端给服务器发消息后,服务器会将消息群发给所有客户端。

服务器端分为Program和Client,在Program中进行Ip和端口的绑定并与客户端建立连接,消息的接收和发送放在Client中、

服务端之Program:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Net.WebSockets;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace _022_聊天室_socket_tcp服务器端 {
  10. class Program {
  11. static List<Client> clientList = new List<Client>();
  12. // 广播消息
  13. public static void BroadcastMessage(string message)
  14. {
  15. var notConnectedList = new List<Client>();
  16. foreach (var client in clientList)
  17. {
  18. if (client.Connected)
  19. client.SendMessage(message);
  20. else
  21. {
  22. notConnectedList.Add(client);
  23. }
  24. }
  25. foreach (var temp in notConnectedList)
  26. {
  27. clientList.Remove(temp);
  28. }
  29. }
  30. static void Main(string[] args) {
  31. Socket tcpServer = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
  32. tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.101"),7788));
  33. tcpServer.Listen(100);
  34. Console.WriteLine("server running...");
  35. while (true)
  36. {
  37. Socket clientSocket = tcpServer.Accept();
  38. Console.WriteLine("a client is connected !");
  39. Client client = new Client(clientSocket);//把与每个客户端通信的逻辑(收发消息)放到client类里面进行处理
  40. clientList.Add(client);
  41. }
  42. }
  43. }
  44. }

服务端之Client:

  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. namespace _022_聊天室_socket_tcp服务器端 {
  9. // 用来跟客户端做通信
  10. class Client
  11. {
  12. private Socket clientSocket;
  13. private Thread t;
  14. private byte[] data = new byte[1024];//这个是一个数据容器
  15. public Client(Socket s)
  16. {
  17. clientSocket = s;
  18. //启动一个线程 处理客户端的数据接收
  19. t = new Thread(ReceiveMessage);
  20. t.Start();
  21. }
  22. // 接收数据
  23. private void ReceiveMessage()
  24. {
  25. //一直接收客户端的数据
  26. while (true)
  27. {
  28. //在接收数据之前 判断一下socket连接是否断开
  29. if (clientSocket.Poll(10, SelectMode.SelectRead))
  30. {
  31. clientSocket.Close();
  32. break;//跳出循环 终止线程的执行
  33. }
  34. int length = clientSocket.Receive(data);
  35. string message = Encoding.UTF8.GetString(data, 0, length);
  36. //接收到数据的时候 要把这个数据 分发到客户端
  37. //广播这个消息
  38. Program.BroadcastMessage(message);
  39. Console.WriteLine("收到了消息:"+message);
  40. }
  41. }
  42. // 发送消息
  43. public void SendMessage(string message)
  44. {
  45. byte[] data = Encoding.UTF8.GetBytes(message);
  46. clientSocket.Send(data);
  47. }
  48. // 判断是否连接
  49. public bool Connected
  50. {
  51. get { return clientSocket.Connected; }
  52. }
  53. }
  54. }

客户端:因为是基于unity的聊天室,所以首先创建简单的UI界面

代码:

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using System.Text;
  6. using System.Threading;
  7. public class ChatManager : MonoBehaviour
  8. {
  9. public string ipaddress = "192.168.1.101";
  10. public int port = 7788;
  11. public UIInput textInput;
  12. public UILabel chatLabel;
  13. private Socket clientSocket;
  14. private Thread t;
  15. private byte[] data = new byte[1024];//数据容器
  16. private string message = "";//消息容器
  17. void Start () {
  18. ConnectToServer();
  19. }
  20. void Update () {
  21. if (message != null && message != "")
  22. {
  23. chatLabel.text += "\n" + message;
  24. message = "";//清空消息
  25. }
  26. }
  27. void ConnectToServer()
  28. {
  29. clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
  30. //跟服务器端建立连接
  31. clientSocket.Connect( new IPEndPoint(IPAddress.Parse(ipaddress),port) );
  32. //创建一个新的线程 用来接收消息
  33. t = new Thread(ReceiveMessage);
  34. t.Start();
  35. }
  36. // 这个线程方法 用来循环接收消息
  37. void ReceiveMessage()
  38. {
  39. while (true)
  40. {
  41. if (clientSocket.Connected == false)
  42. break;
  43. int length = clientSocket.Receive(data);
  44. message = Encoding.UTF8.GetString(data, 0, length);
  45. //chatLabel.text += "\n" + message;
  46. }
  47. }
  48. // 发送消息
  49. void SendMessage(string message)
  50. {
  51. byte[] data = Encoding.UTF8.GetBytes(message);
  52. clientSocket.Send(data);
  53. }
  54. // 发送按钮点击
  55. public void OnSendButtonClick()
  56. {
  57. string value = textInput.value;
  58. SendMessage(value);
  59. textInput.value = "";
  60. }
  61. void OnDestroy()
  62. {
  63. clientSocket.Shutdown(SocketShutdown.Both);
  64. clientSocket.Close();//关闭连接
  65. }
  66. }

C#编程 socket编程之unity聊天室的更多相关文章

  1. C#编程 socket编程之tcp服务器端和客户端

    基于Tcp协议的Socket通讯类似于B/S架构,面向连接,但不同的是服务器端可以向客户端主动推送消息. 使用Tcp协议通讯需要具备以下几个条件: (1).建立一个套接字(Socket) (2).绑定 ...

  2. C#编程 socket编程之udp服务器端和客户端

    基于Udp协议是无连接模式通讯,占用资源少,响应速度快,延时低.至于可靠性,可通过应用层的控制来满足.(不可靠连接) 使用Udp协议通讯需要具备以下几个条件: (1).建立一个套接字(Socket) ...

  3. C#编程 socket编程之TcpClient,TcpListener,UdpClient

    应用程序可以通过 TCPClient.TCPListener 和 UDPClient 类使用传输控制协议 (TCP) 和用户数据文报协议 (UDP) 服务.这些协议类建立在 System.Net.So ...

  4. 老雷socket编程之PHP利用socket扩展实现聊天服务

    老雷socket编程之PHP利用socket扩展实现聊天服务 socket聊天服务原理 PHP有两个socket的扩展 sockets和streamssockets socket_create(AF_ ...

  5. 老雷socket编程之websocket实现

    老雷socket编程之websocket实现 我们主要实现私聊和群聊两个功能,要在web端实现想微信QQ那样的即时通讯的功能,我们需要了解一下websocket.websocket是一种可以双向通讯的 ...

  6. [深入浅出WP8.1(Runtime)]Socket编程之UDP协议

    13.3 Socket编程之UDP协议 UDP协议和TCP协议都是Socket编程的协议,但是与TCP协议不同,UDP协议并不提供超时重传,出错重传等功能,也就是说其是不可靠的协议.UDP适用于一次只 ...

  7. iPhone socket 编程之BSD Socket篇

    iPhone socket 编程之BSD Socket篇 收藏在进行iPhone网络通讯程序的开发中,不可避免的要利用Socket套接字.iPhone提供了Socket网络编程的接口CFSocket, ...

  8. 使用socket.io打造公共聊天室

    最近的计算机网络课上老师开始讲socket,tcp相关的知识,当时脑袋里就蹦出一个想法,那就是打造一个聊天室.实现方式也挺多的,常见的可以用C++或者Java进行socket编程来构建这么一个聊天室. ...

  9. PHP Socket 编程之9个主要函数的使用之测试案例

    php的socket编程算是比较难以理解的东西吧,不过,我们只要理解socket几个函数之间的关系,以及它们所扮演的角色,那么理解起来应该不是很难了,在笔者看来,socket编程,其实就是建立一个网络 ...

随机推荐

  1. DNS原理及实战配置指南

    目录 DNS简介 DNS域名结构介绍 顶级域名 DNS工作原理 工作模式和端口 资源记录 安装bind(详细) 实战:配置一个正反向解析 实战:配置DNS转发 实战:配置DNS主从 实战:子域授权 实 ...

  2. CF892E Envy[最小生成树]

    题意:有一张 $n$ 个点$ m $条边的连通图.有$Q$ 次询问.每次询问给出 $k[i]$ 条边,问这些边能否同时出现在一棵最小生成树上.$n,m,Q,\sum k\le 500000$. 这题利 ...

  3. Mybatis 解决问题的记录与博客

    问题:mybatis 空值映射的问题Mybatis在使用resultMap来映射查询结果中的列,如果查询结果中包含空值的列(不是null),则Mybatis在映射的时候,不会映射这个字段 https: ...

  4. 关于C# Dockpanel的一些入门的基本操作

    关于C# Dockpanel的一些入门的基本操作 原文链接:https://blog.csdn.net/Lc1996Jm/article/details/51881064 一.引用: 1.建立一个Wi ...

  5. django之表多对多建立方式、form组件、钩子函数 08

    目录 多对多三种创建方式 1.全自动(用ManyToManyField创建第三张表) 2.纯手写 3.半自动 form组件 引入 form组件的使用 forms组件渲染标签 form表单展示信息 fo ...

  6. 【Springboot】Springboot整合Ehcache

    刚刚项目上线了,记录下使用的技术...... EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. Ehcache的特点 ( ...

  7. Prism框架中View与Region关联的几种方式

    Prism.Regions命名空间下有2个重要接口:IRegionManager.IRegion IRegionManager接口中的方法与属性:AddToRegion().RegisterViewW ...

  8. 【Python网络】网络协议篇

    OSI七层协议 互联网协议按照功能不同分为OSI七层 或 TCP/IP五层 或 TCP/IP四层 每层运行常见物理设备 TCP/IP五层模型讲解 每层都运行特定的协议,越往上越靠近用户,越往下越靠近硬 ...

  9. javaScript第二篇

    事件处理函数 javaScript响应用户操作等都是通过事件处理来触发;其基本形式为 event = "javaScript statement(s);" 事件 = "事 ...

  10. 51 Nod 1163 最高的奖励

    1163 最高的奖励  基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励.在结束时间之前完成 ...