基于Socket实现客户端和服务端的Tcp通信(C#)

0.前言

使用C#和Unity实现复刻Liar’s bar中的功能
软件开发大作业
本系列文章用于记录与分享开发过程中使用到的知识点,以及常见错误
本文主要描述有关网络编程的内容

目录

  • 0.前言
  • 1.使用Socket搭建Server
    • 1.1Server端的Socket连接
    • 1.2 Server端接收Client的信息
    • 1.3 Server端接收信息后,处理信息
    • 1.4 Server端给Client端发送信息
    • 1.5 小结
  • 2.Client端 搭建Socket连接
    • 2.0 前言
    • 2.1 连接服务器
    • 2.2 Unity中怎么转换Json
  • 3.远程联机
    • 3.1SakuraFrp
    • 3.2 Client端

1.使用Socket搭建Server

1.1Server端的Socket连接

public static void waitClient{//ipv4地址,此处使用localhoststring host = "127.0.0.1";//端口号,需要与其他端口占用不同,例如3306,8080等//client端与此处端口相同即可string port = "6657";//创建ipIPEndPoint pos = new IPEndPoint(IPAddress.Parse(host), port);Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);listener.Bind(pos);//最多接收3个人的连接,参数可以改变listener.Listen(3);Socket sclient;String name;byte[] buffer = new byte[1024];Player p;int len;//监听客户端的连接while (true){//接收到客户端连接 保存到sclient对象中sclient = listener.Accept();//并给这个对象单独开一个监听线程,在文后会再详细说明Thread listen = new Thread(new ParameterizedThreadStart(listenerClient));listen.Start(sclient);}
}static void Main(String[] args){//为等待客户端连接创建一个线程Thread wait = new Thread(new ThreadStart(waitClient));wait.Start();
}

1.2 Server端接收Client的信息

 static void listenerClient(Socket s){byte[] buffer = new byte[1024];while (true){Message msg;try{int len = s.Receive(buffer);string str = Encoding.UTF8.GetString(buffer, 0, len);//根据&进行分割//由于客户端和服务端发送信息有延迟,//传输时在每个信息后面加&可以分清楚信息的范围foreach (string s in str.Split('&')){if (s.Length > 0){//反序列成msg对象 发送的是json格式的数据//这里用的是NewtonSoft.Json可以在NuGet引入依赖msg = JsonConvert.DeserializeObject<Message>(s);//将msg加入到queue中//上锁 使线程同步//这里的toDoListLock的声明为        
//private static readonly object toDoListLock = new object();lock (toDoListLock){//这里的toDoList的声明为:
//private static Queue<Message> toDoList = new Queue<Message>();toDoList.Enqueue(msg);}}}}catch (SocketException){//常见try-catch,不做过多赘述break;}}}
//常见Msg类
class Message
{public String type;public String info;//构造器public Message(string type, string info){this.type = type;this.info = info;}
}

1.3 Server端接收信息后,处理信息

//也需要给本类启动一个线程,
//Thread toDo = new Thread(new ThreadStart(toDoListClient));
//toDo.startstatic void toDoListClientOperation(){while (true){//循环监听,如果此时队列中无信息就进入下次循环if (toDoList.Count == 0){continue;}//得到msg对象Message msg = toDoList.Dequeue();switch(msg.type){//根据类型进行对应操作即可 此处省略}}}

1.4 Server端给Client端发送信息

 static void sendMsg(string type, string info,Socket socket){Message msg = new Message(type, info);string str = JsonConvert.SerializeObject(msg);//将json字符串转成字符数组并最后加上一个&//添加&的原因已在1.2中说明,此处省略byte[] bytes = Encoding.UTF8.GetBytes(str + '&');//发送信息socket.Send(bytes);}

1.5 小结

大体思路就是一个线程用于接收Client的连接,一个线程用于接收Client的信息,一个线程专门用于处理信息
面对Server端要被多个Client端连接时,可以创建数组保存这些Socket

2.Client端 搭建Socket连接

2.0 前言

由于Client端与Server端搭建类似,此处只写如何连接,后面的收发信息则不过多赘述

2.1 连接服务器

//与Server端保持一致
string host = "127.0.0.1";
string port = "6657";
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(host, port);

2.2 Unity中怎么转换Json

在Unity项目中引入NewtonSoft.Json.dll后发现经常会导致程序崩溃,
Unity中自带一个处理JSON的类:JsonUtility 类
常用API:
JsonUtility.ToJson(param)
JsonUtility.FromJson<>(param)

3.远程联机

这里简单提供一种思路:内网穿透
在代码实现方面与上面相同,只不过host和port要改变

3.1SakuraFrp

这里用SakuraFrp实现内网穿透
搭建时本机IP去看当前联网的属性中IPV4的地址
(注意:此时开启服务器的电脑本地IP不是127.0.0.1,要去Wlan那里看具体的ip是什么)
搭建选择TCP
附SakuraFrp的官方地址:https://www.natfrp.com/
Server端的ip填写ipv4的地址,端口就写搭建时开放的端口
(注:Server端电脑的端口应该设置为开放)
笔者曾使用该软件进行游戏联机,所以想到这里能用(doge)

3.2 Client端

启动SakuraFrp该隧道后,在日志信息中会给出映射的ip和端口
日志信息
冒号前面是host,后面是port。
则Client端的host=“211.149.167.185”,port=28821

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【mysql】如何查看大表记录行数

目录 1. 使用 ANALYZE TABLE 和 SHOW TABLE STATUS2. 查询 INFORMATION_SCHEMA 表3. 使用索引统计信息4. 维护行数缓存5. 使用分区计数 1. 使用 ANALYZE TABLE 和 SHOW TABLE STATUS 1.ANALYZE TABLE 可以更新表的统计信息&#xff0c;然后使用 SHOW TABLE STATUS 来查看估算的…

文件断点续传(视频播放,大文件下载)

客户端每次请求取大文件部分数据。 浏览器播放mp4视频时&#xff0c;会首先传Range消息头&#xff0c;检测到206状态码&#xff0c;和Content-Range&#xff0c;Accept-Ranges 会自动请求余下数据。后端需要在文件任意偏移量取数据。 参考&#xff1a; springboot项目实现断…

游戏AI实现-寻路算法(A*)

A*&#xff08;A-star&#xff09;是一种图遍历和寻路算法&#xff0c;由于其完整性、最优性和最佳效率&#xff0c;它被用于计算机科学的许多领域。给定一个加权图、一个源节点和一个目标节点&#xff0c;该算法将找到从源到目标的最短路径&#xff08;相对于给定的权重&#…

any/all 子查询优化规则的原理与解析 | OceanBase查询优化

背景 在通常情况下&#xff0c;当遇到包含any/all子查询的语句时&#xff0c;往往需要遵循嵌套执行的方式&#xff0c;因此其查询效率较低。Oceanbase中制定了相应的any/all子查询优化规则&#xff0c;能够能够识别并优化符合条件的any/all子查询&#xff0c;从而有效提升查询…

[HNOI2002] 营业额统计 STL - set集合

文章目录 [HNOI2002] 营业额统计题目描述样例输入 #1样例输出 #1 提示题解相关知识点set [HNOI2002] 营业额统计 STL - set解题 题目描述 Tiger 最近被公司升任为营业部经理&#xff0c;他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger 拿出…

汽车供应链 “剧变”开始,“智能感知潜在龙头”诞生

智能汽车产业链“剧变”已经开启&#xff0c;智能感知软硬件能力的权重正在不断被放大。 比如满足高阶泊车的第二代AK2超声波传感器、满足人机共驾场景需求的电子外后视镜&#xff08;CMS&#xff09;、iTOF 3D成像视觉感知&#xff08;用于舱内监控&#xff09;等新产品&…

Latex中表格添加底部文本注释并调整对齐

如何实现从第一个表到第三个表的转换&#xff0c; 其中主要涉及到两点&#xff1a; &#xff08;1&#xff09;底部脚注与表格自动对齐并缩进换行 &#xff08;2&#xff09;表格自适应页面宽度 底部脚注的对齐与换行缩进需要用到 \usepackage{threeparttable} \usepackage{…

SQL 查询方式比较:子查询与自连接

在 SQL 中&#xff0c;子查询和自连接是两种常见的查询方式&#xff0c;它们的功能虽然可以相同&#xff0c;但实现的方式不同。本文通过具体示例&#xff0c;深入探讨这两种查询方式&#xff0c;并配合数据展示&#xff0c;帮助大家理解它们的使用场景和差异。 数据示例 假设…

html基础-认识html

1.什么是html html是浏览器可以识别的的标记语言&#xff0c;我们在浏览器浏览的网页就是一个个的html文档 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>认识html</title> </head> <body><h1…

linux 无网络安装mysql

下载地址 通过网盘分享的文件&#xff1a;mysql-5.7.33-linux-glibc2.12-x86_64.tar.gz 链接: https://pan.baidu.com/s/1qm48pNfGYMqBGfoqT3hxPw?pwd0012 提取码: 0012 安装 解压 tar -zxvf mysql-5.7.33-linux-glibc2.12-x86_64.tar.gz mv /usr/mysql-5.7.33-linux-glibc2.1…

利用高德API获取整个城市的公交路线并可视化(七)

本篇文章是对我们从高德拿到的公交/地铁的json文件的精细化处理的一个深入解析&#xff0c;通过对这些原始数据进行详细的清洗、转换和分析&#xff0c;我们通过对数据的质量和可用性的提升&#xff0c;来为后续的数据精细化处理和研究做基础数据的支撑&#xff0c;从而为后续的…

OGV格式如何转换成MP4格式?五款视频格式转换工具

在数字时代&#xff0c;视频已成为我们日常生活、工作和学习中不可或缺的一部分。而不同的设备和平台往往支持不同的视频格式&#xff0c;这就需要对视频进行格式转换。 OGV&#xff08;Ogg Video File&#xff09;是一种使用OGG开源格式的容器&#xff0c;用于存储带或不带音频…

番外篇 | Hyper-YOLO:超图计算与YOLO架构相结合成为目标检测新的SOTA !

前言:Hello大家好,我是小哥谈。Hyper-YOLO,该方法融合了超图计算以捕捉视觉特征之间复杂的高阶关联。传统的YOLO模型虽然功能强大,但其颈部设计存在局限性,限制了跨层特征的融合以及高阶特征关系的利用。Hyper-YOLO在骨干和颈部的联合增强下,成为一个突破性的架构。在COC…

C语言小练习-打印字母倒三角

编写一个程序&#xff0c;在用户输入某个大写字母后&#xff0c;产生一个金字塔图案。 #include <stdio.h>int main(int argc,char *argv[]) {char ch; loop:printf("请输入大写字母&#xff01;\n");scanf("%c",&ch);getchar();if(ch < A ||…

FutureCompletableFuture实战

1. Callable&Future&FutureTask介绍 直接继承Thread或者实现Runnable接口都可以创建线程&#xff0c;但是这两种方法都有一个问题就是&#xff1a;没有返回值&#xff0c;也就是不能获取执行完的结果。因此java1.5就提供了Callable接口来实现这一场景&#xff0c;而Fu…

什么是MyBatis

MyBatis是一款优秀的持久层框架&#xff0c;它支持定制化SQL、存储过程以及高级映射。以下是关于MyBatis的详细介绍&#xff1a; 一、MyBatis的起源与发展 MyBatis本是Apache的一个开源项目iBATIS&#xff0c;2010年这个项目由Apache迁移到了Google Code&#xff0c;并且改名…

阿尔茨海默症数据集,使用yolo,voc,coco格式对2013张原始图片进行标注,可识别轻微,中等和正常的症状

阿尔茨海默症数据集,使用yolo&#xff0c;voc&#xff0c;coco格式对2013张原始图片进行标注&#xff0c;可识别轻微&#xff0c;中等&#xff0c;严重和正常的症状 数据集分割 训练组100&#xff05; 2013图片 有效集&#xff05; 0图片 测试集&#xf…

[代码随想录21二叉树]二叉树的修改和改造,修剪二叉树,将有序数组转为二叉搜索树

前言 二叉树章节最后的题目了&#xff0c;就是对搜索二叉树的改造&#xff0c; 题目链接 669. 修剪二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 108. 将有序数组转换为二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 一、修剪二叉搜索树 思路&#xff1a;等会…

Android 13 Aosp SystemServer功能裁剪(PackageManager.hasSystemFeature())

系统定制,裁剪Wifi,bt等模块 UI部分可参考: SystemUI 隐藏下拉快捷面板部分模块(wifi,bt,nfc等)入口 Android系统启动后Zygote进程会forkSystemServer进程。SystemServer启动Andorid服务. frameworks/base/services/java/com/android/server/SystemServer.java if (contex…

Scala的惰性求值:深入理解与实践

在编程中&#xff0c;我们经常需要处理那些计算成本高昂或者可能永远不会用到的值。在这种情况下&#xff0c;惰性求值&#xff08;Lazy Evaluation&#xff09;是一种非常有用的策略。它允许我们推迟计算&#xff0c;直到这些值真正需要被使用。Scala&#xff0c;作为一种多功…