System.Sockets中的C#接收数据包 [英] C# Receiving Packet in System.Sockets

查看:57
本文介绍了System.Sockets中的C#接收数据包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的客户端服务器应用程序中,我想知道如何制作一个数据包并通过客户端将其发送到服务器

In my Client Server Application i wondered how to make a packet and send it to the server via the Client

然后在服务器上,我识别出这是哪个数据包,并发送适当的重播

Then on the server i recognize which packet is this and send the proper replay

但是突然间,我遇到了这个话题,这让我担心我是否会陷入这个问题

but suddenly i got across this topic and it make me worry if i may fall in this problem

问题

设计人员最常见的初学者错误之一TCP/IP协议的前提是它们假定消息边界是保留.例如,他们假设一个发送"将导致单个接收".

One of the most common beginner mistakes for people designing protocols for TCP/IP is that they assume that message boundaries are preserved. For example, they assume a single "Send" will result in a single "Receive".

部分应归咎于某些TCP/IP文档.很多人读有关TCP/IP如何保留数据包的信息-必要时将其拆分并在接收方重新订购和重新组装它们.这是完全正确;但是,单个发送"不会发送单个包.

Some TCP/IP documentation is partially to blame. Many people read about how TCP/IP preserves packets - splitting them up when necessary and re-ordering and re-assembling them on the receiving side. This is perfectly true; however, a single "Send" does not send a single packet.

本地计算机(环回)测试证实了这种误解,因为通常当客户端和服务器位于同一台计算机上时沟通速度足够快,单个发送"实际上就可以对应单接收".不幸的是,这只是一个巧合.

Local machine (loopback) testing confirms this misunderstanding, because usually when client and server are on the same machine they communicate quickly enough that single "sends" do in fact correspond to single "receives". Unfortunately, this is only a coincidence.

通常,在尝试部署Internet解决方案(增加客户端与客户端之间的延迟服务器)或尝试发送大量数据(要求碎片).不幸的是,在这一点上,该项目通常是在最后阶段,有时应用程序协议甚至已发布!

This problem usually manifests itself when attempting to deploy a solution to the Internet (increasing latency between client and server) or when trying to send larger amounts of data (requiring fragmentation). Unfortunately, at this point, the project is usually in its final stages, and sometimes the application protocol has even been published!

真实的故事:我曾经在一家开发自定义客户端/服务器软件的公司工作.原始的通信代码已做到这一点常见的错误.但是,它们都位于专用网络上,高端硬件,所以根本的问题只发生了很久很少.做到这一点时,运营商只需将其归纳为有问题的Windows操作系统"或另一个网络故障",然后重新启动.我的其中一个这家公司的任务是改变沟通范围,包括更多信息;当然,这引起了问题的显现定期,整个应用程序协议必须更改为修理它.真正令人惊讶的是,该软件已被用于20年无数的24x7自动化系统;从根本上讲坏了,没人注意到.

True story: I once worked for a company that developed custom client/server software. The original communications code had made this common mistake. However, they were all on dedicated networks with high-end hardware, so the underlying problem only happened very rarely. When it did, the operators would just chalk it up to "that buggy Windows OS" or "another network glitch" and reboot. One of my tasks at this company was to change the communication to include a lot more information; of course, this caused the problem to manifest regularly, and the entire application protocol had to be changed to fix it. The truly amazing thing is that this software had been used in countless 24x7 automation systems for 20 years; it was fundamentally broken and no one noticed.

那么我该如何发送类似AUTH_CALC,VALUE1 = 10,VALUE2 = 12的数据包并以安全的方式从服务器接收它...

So how could i send something like AUTH_CALC,VALUE1=10,VALUE2=12 packet and receive it from the server in a safe way...

如果您想举一个我在这里做的事的例子,下面是

And if you wanna an example of what i am doing here it is below

[客户]

Send(Encoding.ASCII.GetBytes("1001:UN=user123&PW=123456")) //1001 is the ID

[服务器]

private void OnReceivePacket(byte[] arg1, Wrapper Client)
{
    try
    {
        int ID;
        string V = Encoding.ASCII.GetString(arg1).Split(':')[0];
        int.TryParse(V, out ID);

        switch (ID)
        {
            case 1001://Login Packet
                AppendToRichEditControl("LOGIN PACKET RECEIVED");
                break;

            case 1002:
                //OTHER IDs
                break;

            default:
                break;
        }
    }
    catch { }         
}

那么这是构造Message并在服务器上处理它的好方法吗?

So is this is a good way to structure a Message and handling it on the server ?

还可以使用ASCII或UTF8更好的编码吗?

Also which is better encoding to use ASCII or UTF8 ?

推荐答案

最好的方法是使用长度指示器.假设您要发送10000字节的文件,请先发送文件的长度并接收确认,即从另一端接收"OK"字符串,然后继续逐块发送10,000字节(可能是您可以占用4096字节).两次发送4096字节,最后一次发送2000奇数字节.在接收方,没有保证,对于一次发送,您将收到整个4096字节,因此您需要等待直到获得4096字节,然后再处理下一个4096字节.

The best way you can do is by using length indicator. Suppose you are sending a file of 10000 bytes, first send the length of the file and receive the ack i.e "OK" string from other side, then keep on sending 10,000 bytes chunk by chunk(may be u can take 4096 bytes). Send 4096 bytes each time for two time and send 2000 odd bytes on the last chunk. On the receiver side there is no gauranty that for one send you will receive the whole 4096 bytes, so you need to wait until u get 4096 bytes and then proceed with next 4096 bytes.

这篇关于System.Sockets中的C#接收数据包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆