zoukankan      html  css  js  c++  java
  • Socket Programming in C#--Multiple Sockets

    Now lets say you have two sockets connecting to either two different servers or same server (which is perfectly valid) . One way is to create two different delegates and attach a different delegate to different BeginReceive function. What if you have 3 sockets or for that matter n sockets , this approach of creating multiple delegates does not fit well in such cases. So the solution should be to use only one delegate callback. But then the problem is how do we know what socket completed the operation.

    Fortunately there is a better solution. If you look at the BeginReceive function again, the last parameter is a state is an object. You can pass anything here . And whatever you pass here will be passed back to you later as the part of parameter to the callback function. Actually this object will be passed to you later as a IAsyncResult.AsyncState. So when your callback gets called, you can use this information to identify the socket that completed the operation. Since you can pass any thing to this last parameter, we can pass a class object that contains as much information as we want. For example we can declare a class as follows:

    public class CSocketPacket
    {
        public System.Net.Sockets.Socket thisSocket;
        public byte[] dataBuffer = new byte[1024];
    }

    and call BeginReceive as follows:

    CSocketPacket theSocPkt = new CSocketPacket ();
    theSocPkt.thisSocket = m_socClient;
    // now start to listen for any data...
    m_asynResult = m_socClient.BeginReceive (theSocPkt.dataBuffer ,0,theSocPkt.dataBuffer.Length ,SocketFlags.None,pfnCallBack,theSocPkt);

    and in the callback function we can get the data like this:

    public void OnDataReceived(IAsyncResult asyn)
    {
        try
        {
            CSocketPacket theSockId = (CSocketPacket)asyn.AsyncState ;
            //end receive...
            int iRx = 0 ;
            iRx = theSockId.thisSocket.EndReceive (asyn);
            char[] chars = new char[iRx + 1];
            System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
            int charLen = d.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);
            System.String szData = new System.String(chars);
            txtDataRx.Text = txtDataRx.Text + szData;
            WaitForData();
        }
        catch (ObjectDisposedException )
        {
            System.Diagnostics.Debugger.Log(0,"1"," OnDataReceived: Socket has been closed ");
        }
        catch(SocketException se)
        {
            MessageBox.Show (se.Message );
        }
    }

    To see the whole application download the code and you can see the code.

    There is one thing which you may be wondering about. When you call BeginReceive, you have to pass a buffer and the number of bytes to receive. The question here is how big should the buffer be. Well, the answer is it depends. You can have a very small buffer size say, 10 bytes long and if there are 20 bytes ready to be read, then you would require 2 calls to receive the data. On the other hand if you specify the length as 1024 and you know you are always going to receive data in 10-byte chunks you are unnecessarily wasting memory. So the length depends upon your application.

  • 相关阅读:
    MongoDB 安装记录
    Vue.JS 对比其他框架
    CSRF攻击原理以及防御
    浏览器何时发送一个Option请求
    Html5 Canvas核心技术(图形,动画,游戏开发)--基础知识
    CSSOM之getboundingclientrect和getclientrects
    CSSOM之getComputedStyle,currentStyle,getPropertyValue,getAttribute
    nodejs 访问mysql
    HTTP请求中的form data和request payload的区别
    html5 drap & drop
  • 原文地址:https://www.cnblogs.com/frustrate2/p/3312677.html
Copyright © 2011-2022 走看看