WAN 上的 TCP/UDP 套接字服务器

2024-01-20

我用 C# 编写了一个套接字服务器,它将用作我参与的一个小型游戏项目的基本设计。套接字服务器在局域网上工作正常。我能够在服务器和客户端之间完全正常通信。然而,在 WAN 上,服务器从客户端接收到所有正确的消息,但客户端没有从服务器接收到任何消息。客户端和服务器都位于路由器后面,但只有服务器的路由器具有转发的端口。当客户端连接到服务器时,我获得连接的 IP 地址。由于客户端位于 NAT 之后,我是否需要从发送方收集更多信息?我认为客户端可以设置端口转发,但这会对游戏产生非常反作用。我能得到的任何帮助将不胜感激。如果您需要代码,请告诉我。提前致谢。

用于从客户端建立 TCP 连接

public string ConnectionAttempt(string ServeIP, string PlayUsername)
    {
        username = PlayUsername;

        try
        {

            connectionClient = new TcpClient(ServeIP,TCP_PORT_NUMBER);
            connectionClient.GetStream().BeginRead(readbuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(DoRead), null);

            Login(username);
            ipAddress = IPAddress.Parse(((IPEndPoint)connectionClient.Client.RemoteEndPoint).Address.ToString());
            servIP = new IPEndPoint(ipAddress,65002);
            listenUDP = new IPEndPoint(ipAddress, 0);

            UDPListenerThread = new Thread(receiveUDP);
            UDPListenerThread.IsBackground = true;
            UDPListenerThread.Start();
            return "Connection Succeeded";
        }
        catch(Exception ex) {
            return (ex.Message.ToString() + "Connection Failed");
        }
    }

侦听线程上的 UDP 消息。

private void receiveUDP()
    {
        System.Net.IPEndPoint test = new   System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
        System.Net.EndPoint serverIP = (System.Net.EndPoint)test;
        server.Bind(serverIP);

        EndPoint RemoteServ = (EndPoint)servIP;
        while (true)
        {
            byte[] content = new byte[1024];
            int  data = server.ReceiveFrom(content, ref RemoteServ);

            string message = Encoding.ASCII.GetString(content);
            result = message;

            ProcessCommands(message);

        }
    }

服务器TCP连接监听器:

private void ConnectionListen()
    {
        try
        {
            listener = new TcpListener(System.Net.IPAddress.Any, PORT_NUM);
            listener.Start();

            do
            {
                UserConnection client = new UserConnection(listener.AcceptTcpClient());
                client.LineRecieved += new LineRecieve(OnLineRecieved);
                UpdateStatus("Someone is attempting a login");

            } while (true);
        }
        catch
        {
        }
    }

服务器UDP监听器:

private void receiveUDP()
    {
        System.Net.IPEndPoint test = new System.Net.IPEndPoint(System.Net.IPAddress.Any, UDP_PORT);
        System.Net.EndPoint serverIP = (System.Net.EndPoint)test;
        trans.Bind(serverIP);
        System.Net.IPEndPoint ipep = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
        System.Net.EndPoint Remote = (System.Net.EndPoint)ipep;

        while (true)
        {

            byte[] content = new byte[1024];

            int recv = trans.ReceiveFrom(content,ref Remote);


            string message = Encoding.ASCII.GetString(content);
            string[] data = message.Split((char)124);
            //UpdateStatus(data[0] + data[1]);

            UserConnection sender = (UserConnection)clients[data[0]];
            sender.RemoteAdd = Remote;
            if (data.Length > 2)
            {
                OnLineRecieved(sender, data[1] + "|" + data[2]);
            }
            else
            {
                OnLineRecieved(sender, data[1]);
            }
        }
    }

用户连接服务器端的设置信息:

Socket trans = new Socket(AddressFamily.InterNetwork,
                 SocketType.Dgram, ProtocolType.Udp); //UDP connection for data transmission in game.

    public PlayerLoc Location = new PlayerLoc();

    public UserConnection(TcpClient client)//TCP connection established first in the Constructor
    {
        this.client = client;
        ipAdd = IPAddress.Parse(((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString());
        ipep = new IPEndPoint(ipAdd, ((IPEndPoint)client.Client.RemoteEndPoint).Port);
        this.client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(StreamReciever), null);
    }

向个人用户发送数据的方法:

public void SendData(string data)//UDP only used during transmission
    {

        byte[] dataArr = Encoding.ASCII.GetBytes(data);
        trans.SendTo(dataArr, dataArr.Length,SocketFlags.None, RemoteAdd); 

    }

客户端必须启动 UDP 通信,以便能够在路由器/防火墙中获得“漏洞”。并且 UDP 服务器必须使用中引用的端点进行回复ReceviedFrom

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WAN 上的 TCP/UDP 套接字服务器 的相关文章

  • 调用许多网络服务的最佳方式?

    我有 30 家子公司 每家都实施了他们的 Web 服务 使用不同的技术 我需要实现一个Web服务来聚合它们 例如 所有子公司的Web服务都有一个名为的Web方法GetUserPoint int nationalCode 我需要实现我的网络服
  • 从 Invoke 方法获取 RETURN

    我正在尝试从另一个线程上的列表框项目中读取值 我尝试创建一种新方法来运行调用命令 我可以设法将命令发送到列表框 例如通过调用方法添加 但我似乎无法得到响应 我似乎无法获取该项目的值 我尝试了几种方法 一旦我将它从空变为字符串 事情就开始变得
  • 通过 SOAP 的 Gmt php 或 UTC C# 等效项

    is C DateTime UtcNow和 PHPdate c 是等价的 我怀疑 因为当我肥皂时 我得到了 C
  • C# Outlook 从收件人获取 CompanyName 属性

    我目前正在使用 C 编写 Outlook 2010 AddIn 我想要的是从我从 AppointmentItem 中提取的 Recipient 对象中获取 CompanyName 属性 因此 有了 AppointmentItem 的收件人
  • 具有多个谓词的 C++11 算法

    功能如std find if来自algorithmheader 确实很有用 但对我来说 一个严重的限制是我只能为每次调用使用 1 个谓词count if 例如给定一个像这样的容器std vector我想同时应用相同的迭代find if 多个
  • 类中是否可以有虚拟类声明?

    我正在为个人项目中框架的各个组件设置一个接口 我突然想到了一些我认为可能对接口有用的东西 我的问题是这是否可能 class a public virtual class test 0 class b public a public clas
  • make_shared<>() 中的 WKWYL 优化是否会给某些多线程应用程序带来惩罚?

    前几天我偶然看到这个非常有趣的演示 http channel9 msdn com Events GoingNative GoingNative 2012 STL11 Magic Secrets作者 Stephan T Lavavej 其中提
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • “没有合适的默认构造函数可用”——为什么会调用默认构造函数?

    我已经查看了与此相关的其他一些问题 但我不明白为什么在我的情况下甚至应该调用默认构造函数 我可以只提供一个默认构造函数 但我想了解它为什么这样做以及它会产生什么影响 error C2512 CubeGeometry no appropria
  • C 与 C++ 中的 JNI 调用不同?

    所以我有以下使用 Java 本机接口的 C 代码 但是我想将其转换为 C 但不知道如何转换 include
  • 在 C++ 代码 gdb 中回溯指针

    我在运行 C 应用程序时遇到段错误 在 gdb 中 它显示我的一个指针位置已损坏 但我在应用程序期间创建了 10 万个这样的对象指针 我怎样才能看到导致崩溃的一个 我可以在 bt 命令中执行任何操作来查看该指针的生命周期吗 谢谢 鲁奇 据我
  • 测验;这个编译了吗?如果是的话它会返回什么(我知道答案)

    我最近发现这个错字 if name find string npos 显然开发者的意思是输入 if name find string npos 但令我惊讶的是发现错误甚至编译 Wall Werror 没有尝试过 pedantic 那么 咖啡
  • C++ 模板可以提供 N 个给定类的公共父类吗?

    我正在寻找一个 C 模板 它可以找到一组给定类的共同父级 例如 class Animal class Mammal public Animal class Fish public Animal class Cat public Mammal
  • 使用 Unity 在 C# 中发送 http 请求

    如何使用 Unity 在 C 中发送 HTTP GET 和 POST 请求 我想要的是 在post请求中发送json数据 我使用Unity序列化器 所以不需要 新的 我只想在发布数据中传递一个字符串并且能够 将 ContentType 设置
  • 如何调用与现有方法同名的扩展方法? [复制]

    这个问题在这里已经有答案了 我有这样的代码 public class TestA public string ColA get set public string ColB get set public string ColC get se
  • 与 Entity Framework Core 2.0 的一对零关系

    我正在使用 C 和 NET Framework 4 7 将 Entity Framework 6 1 3 Code First 库迁移到 Entity Framework Core 我一直在用 Google 搜索 Entity Framew
  • Unity,c++ 本机插件字节数组不匹配

    在我的 C 本机插件中 我有一个调用 vector
  • IDisposable 的显式实现

    虽然有很多关于IDisposable在 SO 上找到 我还没有找到答案 我通常遵循这样的做法 当我的一个班级拥有一个IDisposable对象然后它也实现IDisposable并打电话Dispose在拥有的对象上 然而最近我遇到了一个类 它
  • 如何在c中断言两个类型相等?

    在 C 中如何断言两种类型相等 在 C 中 我会使用 std is same 但搜索 StackOverflow 和其他地方似乎只能给出 C 和 C 的结果 在C中没有办法做到这一点吗 请注意 这不是询问变量是否具有某种类型 而是询问两个类

随机推荐

  • ViewModel 订阅特定属性的 Model 的 PropertyChanged 事件

    我希望在模型中的属性更改时执行 methodToBeCalledWhenPropertyIsSet 我怎么能这样做呢 如果我理解正确的话 我可以添加MyModel PropertyChanged methodToBeCalledWhenPr
  • 从 Linux 为 Windows 交叉编译静态库

    我想在linux下为windows编译静态库 以下是我编译的过程 在linux中使用编译静态库的源代码i586 mingw32msvc cc c static lib c o static lib o 在linux中创建静态库ar rv s
  • UITextField 上的强密码叠加

    我面临着奇怪的覆盖UITextField 我正在使用类型字段textContentType password and isSecureTextEntry true 我还有眼睛按钮 可以通过更改来取消隐藏密码字符isSecureTextEnt
  • Kendo-Grid 列字段验证

    我正在努力使用 API 数据填充 kendo grid 但在一个字段上添加验证也会自动适用于所有其他字段 这是 kendo dataSource 内部的架构 schema model id id fields id editable fal
  • Android 上的 ORMLite 不调用 onCreate

    使用 ORMLite v 4 40 我尝试让我的应用程序运行 但它似乎忽略了 onCreate 函数 我的 DatabaseHelper 看起来像这样 片段样式 public class ORMLiteHelper extends OrmL
  • 动态创建函数/子程序的 AutoHotkey 热键

    自动热键命令Hotkey允许在运行时创建动态热键 但其语法和文档似乎将其限制为内置或现有标签 子例程 这使得much不太有用 热键 键名 标签 选项 有没有办法让它像常规的硬编码热键一样工作 例如 z MsgBox foobar Typic
  • SQL:显示标准差内的平均值和最小值/最大值

    我有以下 SQL 表 Date StoreNo Sales 23 4 34 4323 00 23 4 23 564 00 24 4 34 2345 00 etc 我正在运行一个查询 返回特定时间段内的平均销售额 最大销售额和最小销售额 se
  • Intellij IDEA:找不到“JdbcTemplate”类型的bean

    Intellij IDEA 15 0 3 表示 JdbcTemplate bean 不存在 这是一个 Spring Boot 项目 因此所有需要的 bean 都应该在 boot 内部创建 它工作正常 我可以与我的数据库交互 但 IDEA 将
  • 用于运行 DiskPart 的批处理文件

    我正在尝试开发一个批处理文件来运行并删除 Windows 7 中的隐藏分区 当尝试删除所有分区时 通常我在命令提示符窗口中逐行执行此操作 但试图找出如何创建批处理文件来运行并加快此过程 以下是我在命令提示符下键入的行 disk part R
  • 终结器在其对象仍在使用时启动

    Summary C NET 应该被垃圾收集 C 有一个析构函数 用于清理资源 当对象 A 在我尝试克隆其变量成员之一的同一行被垃圾回收时会发生什么 显然 在多处理器上 有时垃圾收集器会获胜 问题 今天 在 C 培训课程中 老师向我们展示了一
  • 程序化屏幕截图歪曲了最近邻居

    我遇到了屏幕截图 以编程方式使用下面的代码 与图像放大 在我的情况下非常远 并渲染最近邻以保留硬边缘时屏幕上实际显示的内容之间的不一致 我从这些论坛获得了以下屏幕截图代码 但保存的是图像的 双线性 渲染而不是最近邻 UIGraphicsBe
  • 如何在postgresql中将bigint(以毫秒为单位的时间戳)值写入为时间戳

    我试图将我的值存储在带有时区字段的时间戳中 从 1970 年开始以毫秒为单位 select TO CHAR TO TIMESTAMP 1401432881230 DD MM YYYY HH24 MI SS MS 预期的30 5 2014 1
  • 实体框架 - 只有 edmx,没有模板

    我们只想添加 EDMX 文件 而不添加上下文和实体的相应 tt 文件 造成这种情况的原因有多种 但长话短说 我们希望能够拥有 EDMX 并能够在需要时从数据库刷新它 目前 如果我每次 从数据库更新 时删除 tt 文件 它将重新生成我们不需要
  • C# 中的互斥量和信号量是什么?我们需要在哪里实施? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 C 中的互斥量和信号量是什么 我们需要在哪里实施 我们如何在多线程中使用它们 您应该从 MSDN 开始 系统 线程 互斥体 http
  • Paypal Recurring Gem - 暂停付款

    我正在寻找为贝宝经常性宝石 跟随 Rails Cast 设置付款暂停 我不确定是否需要设置 IPN 因为 gem 的文档中没有提及它 我目前拥有的代码不执行任何操作 我在模型中定义了取消重复 但我不确定如何完成代码 因为我很难理解这一切是如
  • 更新 python 包后出现“InvalidRequirement:无效需求,解析错误”错误

    使用更新包 在我的例子中是 IPython 后pip install U ipython运行任何使用入口点的 Python 脚本都会失败并出现以下错误 Traceback most recent call last File home ad
  • 错误:系列的真值不明确 - Python pandas [重复]

    这个问题在这里已经有答案了 我知道这个问题之前已经被问过 但是 当我尝试做一个if声明 我收到错误 我看了这个link https stackoverflow com questions 36921951 truth value of a
  • psql:服务器不支持 SSL,但需要 SSL

    尝试使用命令提示符连接到 postgresql 服务器 使用的命令 psql sslmode require host localhost dbname test 抛出错误 psql 服务器不支持 SSL 但需要 SSL 请帮我解决这个问题
  • 使用 Kotlin 在 Android 应用程序中打开文件选择器

    任务 上传用户可以从设备中选择的图像 我怎样才能打开文件选择器 https en wikipedia org wiki File dialog使用 Kotlin 在 Android 应用程序中按下按钮时出现窗口 在您的活动中 添加按钮单击以
  • WAN 上的 TCP/UDP 套接字服务器

    我用 C 编写了一个套接字服务器 它将用作我参与的一个小型游戏项目的基本设计 套接字服务器在局域网上工作正常 我能够在服务器和客户端之间完全正常通信 然而 在 WAN 上 服务器从客户端接收到所有正确的消息 但客户端没有从服务器接收到任何消