加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C#异步套接字服务器接收问题

发布时间:2020-12-15 23:58:51 所属栏目:百科 来源:网络整理
导读:我在这里实现了关于这篇文章的服务器应用程序: http://www.codeguru.com/csharp/csharp/cs_network/sockets/article.php/c8781#Client1 总结:我正在使用异步套接字ala BeginAccept(..),BeginReceive(..). 我的服务器能够处理多个客户端,一切正常,直到客户
我在这里实现了关于这篇文章的服务器应用程序: http://www.codeguru.com/csharp/csharp/cs_network/sockets/article.php/c8781#Client1

总结:我正在使用异步套接字ala BeginAccept(..),BeginReceive(..).
我的服务器能够处理多个客户端,一切正常,直到客户端执行两个或多个同步发送操作,而无需等待一段时间.客户端没有收到任何错误,因此没有得到通知,服务器没有收到第二条消息!如果客户等待约.第一次发送操作后100ms,一切正常.
我认为当我使用TCP时,我可以确保服务器收到消息. (除了抛出异常)!
你能帮我解决一下吗?

这是WaitForData(..)& OnDataReceive(..)我在服务器中实现的方法

public void WaitForData(MyClient client)
{
    try
    {
        if (pfnCallBack == null)
        {
            pfnCallBack = new AsyncCallback(OnDataReceived);
        }

        iarResult = client.Socket.BeginReceive(client.DataBuffer,client.DataBuffer.Length,SocketFlags.None,pfnCallBack,client);
    }
    catch (SocketException se)
    {
        MessageBox.Show("SocketException@WaitForData" + se.Message);
    }
}
public void OnDataReceived(IAsyncResult asyn)
{
    try
    {
        MyClient user= (MyClient)asyn.AsyncState;
        int iRx = user.Socket.EndReceive(asyn);

        byte[] receivedData = user.DataBuffer;

        MemoryStream memStream = new MemoryStream();
        BinaryFormatter binForm = new BinaryFormatter();
        memStream.Write(receivedData,receivedData.Length);
        memStream.Seek(0,SeekOrigin.Begin);
        MyMessage msg = (MyMessage)binForm.Deserialize(memStream);

        switch (msg.Command)
        {
            case (MyMessage.MyCommand.ConnId):
                this.connId = (int) msg.MyObject;
                tsslConnStatus.Text += " | ID: " + connId.ToString();
            break;

            case (MyMessage.MyCommand.Text):
                MessageBox.Show(msg.MyObject.ToString());
                break;
        }
        WaitForData(server);
    }
    catch (ObjectDisposedException ode)
    {
        MessageBox.Show("ObjectDisposedException@OnReceiveData" + ode.Message);
    }
    catch (SocketException se)
    {
        MessageBox.Show("SocketException@OnReceiveData" + se.Message);
    }
}

客户端调用同步SEND METHOD TWICE或更多!服务器INSTANCEOF MyClient

if (server.Socket.Connected)
{
    BinaryFormatter bf = new BinaryFormatter();
    MemoryStream ms = new MemoryStream();
    bf.Serialize(ms,message);
    MyMessage = new MyMessage(something);
    server.Socket.Send(ms.ToArray());
}

所以,我认为这段代码片段必须足以让你得到我试图使用的想法!
如果您需要更多详细信息或代码片段,请告诉我我会发布它!

感谢名单!

解决方法

TCP是基于流的,而不是基于消息的. One Read可以包含以下任何替代方案:

>消息的一小部分
>一半消息
>一条消息
>一个半消息
>两条消息

因此,您需要使用某种方法来查看是否已到达完整的消息.最常见的方法是:

>添加一个页脚(例如一个空行),表示消息结束
>添加包含消息长度的固定长度标头

更新

简单示例只有标题长度.

服务器端:

var buffer = binaryFormmater.Serialize(myobj);
var length = buffer.Length;
networkStream.Send(length);
networkStream.Send(buffer,buffer.Length);

客户端:

var header = new buffer[4];
// TODO: You need to make sure that 4 bytes have been read.
networkStream.Read(header,4);
var length = BitConverter.ToInt32(buffer);

var readbuffer= new byte[65535];
var bytesLeft = length;
var messageStream = new MemoryStream();
while (bytesLeft > 0)
{
     var read = networkStream.Read(readbuffer,bytesLeft);
     messageStream.Write(readbuffer,read);
     bytesLeft -= read,}

messageStream.Seek(0,SeekOrigin.Begin);
MyMessage msg = (MyMessage)binForm.Deserialize(messageStream);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读