异步套接字,在同一连接上接收多个文件

时间:2012-03-12 14:49:33

标签: c# file sockets

我有一台服务器,它将通过一个连接将多个文件传输到客户端。来自服务器的数据包采用以下格式:      unique_packet_id | FILE_CONTENT

我有onDataReceived函数,我需要像这样工作:

    public class TRACK_ID {
         public string id;
         public string unknown_identifier;
    }

    List<TRACK_ID> TRACKER = new List<TRACK_ID>();

    public void OnDataReceived(IAsyncResult asyn)
    {
        try
        {
            log("OnDataReceived");
            SocketPacket theSockId = (SocketPacket)asyn.AsyncState;

            int iRx = theSockId.thisSocket.EndReceive(asyn); 

            // .. read the data into data_chunk

                // if seperator found, that means we got an first chunk with the id
                if (data_chunk.Contains("|") == true)
                {
                    // extract unique_packet_id from the data
                    // bind unique_packet_id to an some kind of identifier? how!!??
                    TRACK_ID new_track = new TRACK_ID();
                    new_track.id = unique_packet_id;
                    new_track.unknown_identifier = X;

                    TRACKER.add(new_track);

                } else {
                   // no seperator found - we're getting the rest of the data
                   // determinate the unique_packet_id of the incoming data so we can distinguish data/files           
                   string current_packet_id = "";

                   for(int i=0; i<TRACKER.count; i++){
                       if(TRACKER[i].unknown_identifier == X){
                               current_packet_id = TRACKER[i].id; // we found our packet id!
                               break;
                       }
                   }

                   // now we got our packet_id and know where to store the buffer

                }


             WaitForData..
        }

     }

我需要一个变量X,它允许我跟踪存储每个传入缓冲区的位置

如果我关闭每个文件的连接,我可以将unique_packet_id绑定到socket_id(socket_id将是X),但由于我使用相同的连接,socket_id总是保持不变所以我必须为此X变量使用其他东西。

我能想到的其他解决方案是在每个数据块中发送unique_packet_id。但这似乎不是最好的方法。然后我必须将文件缓冲区拆分为块并将id附加到每个块。还有其他方法可以做到这一点吗?谢谢!

1 个答案:

答案 0 :(得分:1)

您没有说明您是使用流套接字还是数据报套接字。

如果您正在使用数据报套接字(例如,您正在使用UDP / IP),那么您将始终一次性收到整个数据包,因此您可以识别数据,因为它与unique_packet_id一致在当前数据包开头的|之前找到。

如果您正在使用流套接字(例如,您使用的是TCP / IP),那么我认为您遇到了问题。您的数据包格式没有分隔或转义,那么您如何知道一个数据包的结束位置以及下一个数据包的开始?

如果您使用的是流套接字,则需要使用例如以下数据包格式:

  • 唯一的数据包ID(例如,以ASCII格式,以CRNL终止 - 或者您选择的任何内容)
  • 内容长度(格式相同)
  • 数据包有效负载

接收方可以找到数据包的末尾,因为它知道有多少字节将成为有效载荷的一部分。

您还需要做好准备,以便获得一小块小包。例如,您的回调函数可能会使用部分唯一数据包ID调用一次,再次使用其余的标头和部分有效负载调用,并再次使用剩余的有效负载并将完整的后续数据包添加到最后。或者,您可以在一次调用回调函数时获得三个完整数据包和部分四分之一。

您提到的另一种可能的解决方案,即在每个数据块中发送unique_packet_id是不可能的,因为发送方不知道数据在传送到接收方时如何被分块。