【问题标题】:Image Stream sent over Socket - Server Deadlock Issue通过 Socket 发送的图像流 - 服务器死锁问题
【发布时间】:2012-08-22 09:33:08
【问题描述】:

我已经实现了一个 Android 应用程序,它使用 SP 相机拍照并通过套接字将其发送到服务器。

我正在使用以下 (JAVA) 代码读取本地存储的图像文件并通过套接字以连续块的形式发送它:

FileInputStream fileInputStream = new FileInputStream( "my_image_file_path" );

int nRead;
byte[] data = new byte[16384];

try {
    while( (nRead = fileInputStream.read(data, 0, data.length)) != -1 ){
        networkOutputStream.write( data, 0, nRead );
    }

} catch( IOException e ){
    e.printStackTrace();
}
fileInputStream.close();

以及以下 (C/C++) 代码来读取它并将其存储在服务器上:

char newbuffer[MAX_BUF_SIZE];
int checkOperation;

ofstream outfile( "image_file_path".c_str(), ofstream::binary );

do{
    checkOperation = read( clientSocketDescriptor, newbuffer, sizeof(newbuffer) );

    if( checkOperation < 0 ){

        cout << "Error in recv() function, received bytes = " << checkOperation << endl;
        exit(1);
    }else if (checkOperation != 0 ){

       /*
        * some data was read
        */
       cout << endl << "READ Bytes: " << checkOperation << endl;
       outfile.write( newbuffer, checkOperation );

       /*
        * emptying buffer for new incoming data
        */
       for(int i = 0; i < sizeof(newbuffer); i++){
          newbuffer[i] = 0;
       }
    }
}while( checkOperation =! 0 );

outfile.close();

Android 客户端应用程序似乎正确地写入了套接字中的所有字节,并成功退出了while 循环。

但是,服务器代码卡在其while 循环的最后一次迭代中,无法继续执行。

  • 为什么服务器无法读取EOF
  • 我发送图片或读取图片的代码不正确吗?

提前感谢您的任何帮助,因为我真的被困住了!

【问题讨论】:

  • 因为你不发送EOF ...

标签: java android c++ sockets stream


【解决方案1】:

你没有关闭networkOutputStream,所以C++代码不知道你已经完成了。

要么你需要关闭输出流——显然,这只有在你不需要发送更多数据时才可行——或者你需要在协议中包含一些元数据,以便在开始编写之前指示如何有更多的数据,或者包括一些事后作为“完成”指标。一般来说,我更喜欢长度前缀 - 如果“完成”指示符自然地出现在数据中,这比担心转义要简单得多。

半途而废就是重复说“这里有一段数据长度 X”,然后是“我完成了,没有更多的区块”消息(例如,可能是“这里有一段长度为 0 的数据” )。这样您就无需事先知道总长度。

【讨论】:

  • 我没有关闭networkOutputStream,因为我需要在图像之后发送一些其他数据(一些带有图像描述的文本文件)。在您看来,对于我的特定用例,最好遵循什么程序?感谢您的时间...
  • 另外,在图像发送完毕后用networkOutputStream.flush()方法刷新流可以解决问题吗?
  • @Matteo:不,只是刷新无济于事——因为 C++ 代码仍然不知道你已经完成了。如果您需要发送其他信息,我会为每条数据添加长度前缀(即图像的一个长度前缀,文本信息的另一个长度前缀等)。如果在开始编写之前很难找出完整长度,则可以使用分块解决方案。
  • @Matteo 如果您不关闭流,则没有 EOF。您似乎认为在每组写入之后都会有一个自动 EOF,尽管 TCP 如何知道将它放在哪里是一个谜,同一流上如何可能有多个 EOF 是另一个问题。
  • @EJP - 我认为当客户端代码退出 while 循环时,EOF 将被放入 automagically。谢谢指出它不是那样的! ;D
猜你喜欢
  • 1970-01-01
  • 2012-08-27
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多