只有一个write()调用通过套接字连接发送数据

sha*_*ord 2 c sockets linux asyncsocket ios

第一个stackoverflow问题!我搜索过......我保证.我没有找到任何解决我的困境的答案.至少可以说,我......是一个严重恶化的问题.总而言之,我正在为游戏开发基础架构,其中移动应用程序(Android应用程序和iOS应用程序)使用套接字与服务器通信以将数据发送到数据库.后端服务器脚本(我称之为BES或后端服务器)是几千行代码.本质上,它有一个main方法接受到套接字的传入连接并将它们分离,以及一个从套接字读取输入并确定如何处理它的方法.大多数代码都在于从数据库发送和接收数据并将其发送回移动应用程序的方法.除了我添加的最新方法之外,它们都可以正常工作.此方法从数据库中获取大量数据,将其编码为JSON对象,然后将其发送回移动应用程序,移动应用程序还从JSON对象解码它并执行它需要执行的操作.我的问题是这个数据非常大,并且大部分时间都没有在一次数据写入中跨越套接字.因此,我在套接字中添加了一个额外的数据写入,通知应用程序它将要接收的JSON对象的大小.但是,在此写入发生后,下一次写入将空数据发送到移动应用程序.

奇怪的是,当我删除发送JSON对象大小的第一个写入时,JSON对象的实际发送工作正常.它只是非常不可靠,我不得不希望它能在一次读取中发送它.为了给这种情况增加更多的奇怪性,当我确定第二次写入发送大量数据的数据大小时,iOS应用程序将正确读取它,但它将数据放在一个空数组的中间.

世界上到底发生了什么?非常感谢任何见解!下面只是我在服务器端的两个写命令的基本片段.

请记住,在这个脚本中的其他任何地方,read和write的工作正常,但这是我连续两次执行写操作的唯一地方.

服务器脚本位于使用Berkeley套接字的本机C中的Ubuntu服务器上,而iOS正在使用名为AsyncSocket的包装器类.

int n;
//outputMessage contains a string that tells the mobile app how long the next message
//(returnData) will be
n = write(sock, outputMessage, sizeof(outputMessage));
if(n < 0)
   //error handling is here
//returnData is a JSON encoded string (well, char[] to be exact, this is native-C)
n = write(sock, returnData, sizeof(returnData));
if(n < 0)
   //error handling is here
Run Code Online (Sandbox Code Playgroud)

移动应用程序进行两次读取调用,并且outputMessage很好,但returnData总是只是一堆空数据,除非我覆盖sizeof(returnData)到一些非常大的数字,在这种情况下,iOS将在其他空数据中间接收数据object(确切地说是NSData对象).值得注意的是,我在AsyncSocket类的iOS端使用的方法读取的数据长度是从第一次写入调用中获取的数据.因此,如果我告诉它读取10000个字节,它将创建一个该大小的NSData对象,并在从套接字读取时将其用作缓冲区.

任何帮助都非常,非常感谢.在此先感谢大家!

Gre*_*ill 6

它只是非常不可靠,我不得不希望它能在一次读取中发送它.

使用TCP成功编程的关键是在应用程序级别没有TCP"数据包"或"块"数据的概念.应用程序只看到一个字节,没有边界.当您write()使用某些数据在发送端调用时,TCP层可以选择以其认为合适的任何方式对数据进行切片和切块,包括将多个块合并在一起.

您可以写两次10个字节,然后读取5个字节,然后读取15个字节 或者你的接收器可能会同时看到20个字节.你不能做的只是"希望"你发送的一些字节块将以相同的块到达另一端.

在您的特定情况下可能发生的事情是两个背靠背写入被合并为一个,并且您的读取逻辑根本无法处理.