为BeginReceive提供的字节

时间:2010-07-03 09:26:20

标签: c# sockets asynchronous msdn

我的程序所做的是,在第一次连接接受时,服务器发送数据 客户端接收然后再次发送(Datasize不会更改) 服务器收到它然后再发回....这个循环继续......

当服务器第二次接收到endreceive()返回的数据时;是0

虽然我找到了解决方案,但我不知道为什么这实际上解决了问题

我在某处读到了一个叫做'脏'缓冲区的东西:s

所以我做的是。

//added line
data = new byte[DataSize];

//now index works fine :s
int index = socket.endreceive(result);

之前我重新使用byte[] data进行发送和接收而不更改其内容,数据发送全部为零

它有效:)

msdn没有帮助我或者我错过了什么? MSDN Link

这是汇总代码

    private void OnSendCallBack(IAsyncResult result)
    {
        int id_client = (int)result.AsyncState;
        try
        {

            int index = clientInfo[id_client].client.EndSend(result);

            clientInfo[id_client].offsetSend += index;
            if (index == 0)
            {
                Console.WriteLine("Index == 0");
                return;
            }
            else if (clientInfo[id_client].offsetSend < DataSize)
            {
                clientInfo[id_client].dataToSend = DataSize - clientInfo[id_client].offsetSend;
                clientInfo[id_client].client.BeginSend(data, clientInfo[id_client].offsetSend, clientInfo[id_client].dataToSend, SocketFlags.None, RecieveCallBack, id_client);
            }
            else 
            {
                clientInfo[id_client].offsetSend = 0;
                clientInfo[id_client].dataToSend = DataSize;
                //*************************************
                data = new byte[DataSize]; // THIS IS THE PROBLEM HERE
                //*************************************
                clientInfo[id_client].client.BeginReceive(data, 0, data.Length, SocketFlags.None, RecieveCallBack, id_client);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Send: " + ex.Message);
        }
    }

private void RecieveCallBack(IAsyncResult result)
    {
        int id_client = (int)result.AsyncState;

        try
        {

            int index = clientInfo[id_client].client.EndReceive(result);

            //byte[] buffer = new byte[DataSize];
            //int received = clientInfo[id_client].client.Receive(buffer);

            clientInfo[id_client].offsetRec += index;
            if (index == 0)
            {
                index = clientInfo[id_client].client.EndReceive(result);
                Console.WriteLine("Index == 0");
                return;
            }
            else if (clientInfo[id_client].offsetRec < DataSize && clientInfo[id_client].offsetRec != 0)
            {
                clientInfo[id_client].dataToReceive = DataSize - clientInfo[id_client].offsetRec;
                clientInfo[id_client].client.BeginReceive(data, clientInfo[id_client].offsetRec, clientInfo[id_client].dataToReceive, SocketFlags.None, RecieveCallBack, id_client);
            }
            else
            {
                clientInfo[id_client].offsetRec = 0;
                clientInfo[id_client].dataToReceive = DataSize;

                if (clientInfo[id_client].RunNumber < RounCount)
                {
                    clientInfo[id_client].RoundTripStat.EndSample();
                    clientInfo[id_client].RoundTripStat.BeginSample(); 
                    clientInfo[id_client].client.BeginSend(data, 0, data.Length, SocketFlags.None, OnSendCallBack, id_client); 
                }

                Close(id_client);
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine("Server: " + ex.Message);
        }
    }

我提供了SendCallback和Receive Callback的代码,因为你可以看到一个asynch命令一次等待一个

1 个答案:

答案 0 :(得分:1)

如果没有更多数据要接收,

EndReceive()将返回0,并且套接字已关闭(即不再接收数据)。

来自您提到的文档:

  

如果远程主机使用Shutdown方法关闭Socket连接,并且已收到所有可用数据,则EndReceive方法将立即完成并返回零字节。

您通常不应该为发送和接收重复使用相同的缓冲区 - 您最终会发送您收到的任何数据,如果您有重叠的发送和接收异步调用,它将最终处于一个非常奇怪的状态,潜在地

如果您一次只执行一个操作,那么“共享”缓冲区是安全的,并且您确保在编写时,您拥有所需的数据,并在那里明确设置。