• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

简易聊天室app实现Unity+C# 客户端,Java 服务器端

武飞扬头像
百彦子烨
帮助1

Unity C# 客户端

UI界面根据个人喜好排版

学新通学新通

                        图1 进入界面                                                        图2 聊天界面

C#脚本代码如下:

Client_dxc.cs

  1.  
    using UnityEngine;
  2.  
    using System.Net.Sockets;
  3.  
    using System.Text;
  4.  
    using System;
  5.  
    using UnityEngine.UI;
  6.  
     
  7.  
    public class Client_dxc : MonoBehaviour
  8.  
    {
  9.  
    public Text GetText;
  10.  
    public InputField InputText;
  11.  
    public InputField ZhuCeInputText;
  12.  
    public Text chatText;
  13.  
    public ScrollRect scrollRect;
  14.  
    public GameObject DengLuJieMian;
  15.  
     
  16.  
    private string SetText;
  17.  
     
  18.  
    private Socket socket;
  19.  
    private byte[] buffer = new byte[1024];
  20.  
     
  21.  
    void Start()
  22.  
    {
  23.  
    //AddressFamily 寻址类型 SocketType 套接字类型 ProtocolType 协议类型
  24.  
    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  25.  
     
  26.  
    //连接服务器
  27.  
    socket.Connect("127.0.0.1", 9999);
  28.  
     
  29.  
    Debug.Log("连接成功!");
  30.  
     
  31.  
    //开始接收信息
  32.  
    readServer();
  33.  
    }
  34.  
     
  35.  
    void Update()
  36.  
    {
  37.  
    huoqu();
  38.  
    }
  39.  
     
  40.  
    //接收信息
  41.  
    void readServer()
  42.  
    {
  43.  
    //Socket异步接收数据
  44.  
    //buffer存储接收到的数据,offset从零开始计数,size要接收的字节数,SocketFlags 值的按位组合
  45.  
    //ReceiveCallback一个用户定义的对象,其中包含接收操作的相关信息。当操作完成时,此对象会被传递给EndReceive(IAsyncResult)委托
  46.  
    socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, null);
  47.  
    }
  48.  
    void ReceiveCallback(IAsyncResult iar)
  49.  
    {
  50.  
    int len = socket.EndReceive(iar);
  51.  
    if (len == 0)
  52.  
    {
  53.  
    return;
  54.  
    }
  55.  
    string str = Encoding.UTF8.GetString(buffer, 0, len);
  56.  
     
  57.  
    SetText = str;
  58.  
    //循环接收数据
  59.  
    readServer();
  60.  
    }
  61.  
     
  62.  
    //发送信息
  63.  
    void sendServer(string msg)
  64.  
    {
  65.  
    //将字符串转换为UTF-8编码的字节数组
  66.  
    var outputBuffer = Encoding.UTF8.GetBytes(msg);
  67.  
     
  68.  
    //将数据异步发送到连接的 Socket
  69.  
    //BoutputBuffer包含要发送的数据,SocketFlags 值的按位组合,callback:AsyncCallback 委托,state:Object 包含此请求的状态信息的对象
  70.  
    socket.BeginSend(outputBuffer, 0, outputBuffer.Length, SocketFlags.None, null, null);
  71.  
    }
  72.  
     
  73.  
    //获取信息输出到信息面板上
  74.  
    public void huoqu()
  75.  
    {
  76.  
    if (SetText != "")
  77.  
    {
  78.  
    string addText = "\n " SetText;
  79.  
    //将获取的信息添加到信息面板中
  80.  
    chatText.text = addText;
  81.  
    SetText = "";
  82.  
     
  83.  
    //强制画布更新内容
  84.  
    Canvas.ForceUpdateCanvases();
  85.  
    //垂直滚动位置,以 0 到 1 之间的值表示,0 表示位于底部
  86.  
    scrollRect.verticalNormalizedPosition = 0f;
  87.  
    Canvas.ForceUpdateCanvases();
  88.  
    }
  89.  
    }
  90.  
     
  91.  
    //绑定“发送”按钮(群发消息)
  92.  
    public void qunInput()
  93.  
    {
  94.  
    if (InputText.text != "")
  95.  
    {
  96.  
    string msg = "Mass:" InputText.text "\r\n";
  97.  
    sendServer(msg);
  98.  
    InputText.text = "";
  99.  
    }
  100.  
     
  101.  
    }
  102.  
     
  103.  
    //绑定“进入”按钮(进入群聊注册用户名)
  104.  
    public void ZhuCe()
  105.  
    {
  106.  
    if (ZhuCeInputText.text != "")
  107.  
    {
  108.  
    string msg = "userName:" ZhuCeInputText.text "\r\n";
  109.  
    sendServer(msg);
  110.  
    DengLuJieMian.SetActive(false);
  111.  
    }
  112.  
     
  113.  
    }
  114.  
     
  115.  
    }
学新通

将脚本挂在Camera上,绑定对应组件及按钮

学新通

 学新通

 学新通

 

Java 服务器端

Main.java

  1.  
    import java.io.IOException;
  2.  
    import java.net.ServerSocket;
  3.  
    import java.net.Socket;
  4.  
     
  5.  
    public class Main {
  6.  
    public static void main(String[] args) {
  7.  
    try {
  8.  
    //创建ServerSocket对象,监听9999端口
  9.  
    ServerSocket serversocket = new ServerSocket(9999);
  10.  
    System.out.println("----------服务器启动----------");
  11.  
    System.out.println("开始监听:");
  12.  
    //创建一个循环,使主线程持续监听
  13.  
    while (true){
  14.  
    //做一个阻塞,监听客户端
  15.  
    Socket socket = serversocket.accept();
  16.  
    //创建一个新的线程,将客户端socket传入
  17.  
    Server server = new Server(socket);
  18.  
    //启动线程
  19.  
    server.start();
  20.  
    }
  21.  
    } catch (IOException e) {
  22.  
    throw new RuntimeException(e);
  23.  
    }
  24.  
    }
  25.  
    }
学新通

Server.java

  1.  
    import java.io.IOException;
  2.  
    import java.io.PrintStream;
  3.  
    import java.net.Socket;
  4.  
    import java.util.Map;
  5.  
    import java.util.Scanner;
  6.  
    import java.util.Set;
  7.  
    import java.util.concurrent.ConcurrentHashMap;
  8.  
    import java.util.regex.Matcher;
  9.  
    import java.util.regex.Pattern;
  10.  
     
  11.  
    public class Server extends Thread{
  12.  
    //创建一个Map集合
  13.  
    private static Map<String,Socket> map = new ConcurrentHashMap<>();
  14.  
    //创建Socket对象
  15.  
    private Socket socket;
  16.  
     
  17.  
    public Server(Socket socket){
  18.  
    this.socket = socket;
  19.  
    }
  20.  
     
  21.  
    //重写run方法
  22.  
    public void run(){
  23.  
     
  24.  
    try {
  25.  
    //获取客户端的输入流
  26.  
    Scanner scanner=new Scanner(socket.getInputStream());
  27.  
    String msg=null;
  28.  
    //写一个循环来持续处理获取到的信息
  29.  
    while (true) {
  30.  
    //判断是否接收到了字符串
  31.  
    if(scanner.hasNextLine()){
  32.  
    //获取信息
  33.  
    msg=scanner.nextLine();
  34.  
    //处理客户端输入的字符串
  35.  
    Pattern pattern=Pattern.compile("\r");
  36.  
    Matcher matcher=pattern.matcher(msg);
  37.  
    msg=matcher.replaceAll("");
  38.  
    //判断字符串是不是以userName:为前缀的
  39.  
    if(msg.startsWith("userName:"))
  40.  
    {
  41.  
    //将字符串从:拆分开,后半部分存入userName中
  42.  
    String userName=msg.split(":")[1];
  43.  
    //注册该用户
  44.  
    userEnroll(userName,socket);
  45.  
    //将Map集合转换为Set集合
  46.  
    Set<Map.Entry<String,Socket>> set=map.entrySet();
  47.  
    //遍历集合,向所有用户发送消息
  48.  
    for(Map.Entry<String,Socket> entry:set)
  49.  
    {
  50.  
    //取得客户端的Socket对象
  51.  
    Socket client=entry.getValue();
  52.  
    //取得client客户端的输出流
  53.  
    PrintStream printstream=new PrintStream(client.getOutputStream());
  54.  
    //向客户端发送信息
  55.  
    printstream.println(userName "加入了群聊!");
  56.  
    }
  57.  
     
  58.  
    continue;
  59.  
    }
  60.  
    //判断字符串是不是以Mass:为前缀的
  61.  
    if(msg.startsWith("Mass:")){
  62.  
    //拆分字符串,获取信息内容
  63.  
    String str=msg.split(":")[1];
  64.  
    //发送群聊信息
  65.  
    MassSend(socket,str);
  66.  
     
  67.  
    }
  68.  
    }
  69.  
     
  70.  
    }
  71.  
    } catch (IOException e) {
  72.  
    throw new RuntimeException(e);
  73.  
    }
  74.  
    }
  75.  
     
  76.  
    //注册用户
  77.  
    private void userEnroll(String userName,Socket socket){
  78.  
    //将键值对添加入Map集合中
  79.  
    map.put(userName,socket);
  80.  
    //打印日志
  81.  
    System.out.println("[用户名为" userName "][客户端为" socket "]上线了!");
  82.  
    System.out.println("积累进入人数为:" map.size() "人");
  83.  
    }
  84.  
     
  85.  
    //发送消息
  86.  
    private void MassSend(Socket socket,String msg) {
  87.  
    try {
  88.  
    //将Map集合转换为Set集合
  89.  
    Set<Map.Entry<String, Socket>> set = map.entrySet();
  90.  
    String SendName = null;
  91.  
    //遍历Set集合找到发起群聊信息的用户
  92.  
    for (Map.Entry<String, Socket> entry : set) {
  93.  
    //判断集合中的值是否与发起群聊的用户相同
  94.  
    if (entry.getValue().equals(socket)) {
  95.  
    //获取键名
  96.  
    SendName = entry.getKey();
  97.  
    break;
  98.  
    }
  99.  
    }
  100.  
    //遍历Set集合将群聊信息发给每一个客户端
  101.  
    for (Map.Entry<String, Socket> entry : set) {
  102.  
    //取得客户端的Socket对象
  103.  
    Socket client = entry.getValue();
  104.  
    //取得client客户端的输出流
  105.  
    PrintStream printStream = new PrintStream(client.getOutputStream());
  106.  
    //发送消息
  107.  
    printStream.println(SendName ":" msg);
  108.  
    }
  109.  
    } catch (IOException e) {
  110.  
    e.printStackTrace();
  111.  
    }
  112.  
    }
  113.  
     
  114.  
    }
学新通

应用测试

本次测试为本机测试,模拟多客户端环境

先启动服务器

然后双开Unity,进入两个用户

服务器端界面如下:

学新通

 客户端聊天界面如下:

学新通

测试通过,可正常运行

将Java服务器端代码打包成jar包,发送到服务器上运行即可

将C#代码中的目标ip地址改为服务器ip,Unity客户端打包apk文件,发送到各个手机端安装运行即可

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiabbjk
系列文章
更多 icon
同类精品
更多 icon
继续加载