我正在为正在设计的 iPhone 应用程序编写服务器应用程序。iPhone 应用程序是用 C# (MonoTouch) 编写的,服务器也是用 C# 编写的 (.NET 4.0)
我在网络层使用异步套接字。服务器允许两个或多个 iPhone(“设备”)相互连接并能够双向发送数据。根据传入的消息,服务器要么自己处理消息,要么将数据中继到与发送设备相同的组中的其他设备。它可以通过首先解码数据包的标头并确定它是什么类型的数据包来做出这个决定。
这是通过以前 8 个字节为两个整数的方式来构建流的,即标头的长度和有效负载的长度(可以比标头大得多)。
服务器从套接字(异步)读取前 8 个字节,因此它具有两个部分的长度。然后它再次读取,直到标题部分的总长度。
然后它对标头进行反序列化,并根据其中的信息,可以查看是否应将剩余数据(有效负载)转发到另一台设备,或者是否应该由服务器本身处理。如果需要将其转发到另一台设备,那么下一步是以 1024 字节为单位读取进入套接字的数据,并通过连接到接收设备的另一个套接字使用异步发送直接写入这些数据。
这减少了服务器的内存需求,因为我没有将整个数据包加载到缓冲区中,然后将其重新发送到接收方。
但是,由于异步套接字的性质,我不能保证在一次读取中接收到整个有效负载,因此必须继续读取直到我收到所有字节。在中继到其最终目的地的情况下,这意味着我正在为从发送者接收到的每个字节块调用 BeginSend(),并将该块转发给接收者,一次一个块。
这样做的问题是,因为我使用的是异步套接字,这使得另一个线程有可能对同一个接收者(因此也是相同的最终目标套接字)进行类似的操作,因此来自两个线程的块很可能会混淆并破坏发送给该收件人的所有数据。例如:如果第一个线程发送一个块,并且正在等待来自发送者的下一个块(因此它可以转发它),那么第二个线程可以发送它的一个数据块,并破坏第一个线程的(以及第二个线程就此而言)数据。
当我写这篇文章时,我只是想知道它是否像锁定套接字对象一样简单?!这会是正确的选择,还是会导致其他问题(例如:通过锁定的套接字接收从远程设备发回的数据时出现问题?)
提前致谢!