2012-12-26 113 views
0

所以我有點泡菜,我有這個代碼運行在桌面.net 4.5,但它不會編譯.NET 3.5中的Windows CE/Windows Mobile 6.1 Pro ...Windows Mobile的問題與ReceiveBufferSize

public void Init() 
     { 
      try 
      { 
       myTcpListener = new TcpListener(myAddress, myPortNumber); 
       myTcpListener.Server.RecieveBufferSize = 500000; 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 
     } 

也嘗試使用TcpClient.ReceiveBufferSize = 500000;但這會引發異常。

一個未知的,無效的,或不受支持的選項或水平在 的getsockopt或setsockopt調用指定

我有點不確定如何進行......目的是爲了有大的緩衝區足以容納500.000字節......也許我需要以不同的方式處理這個問題。

編輯:這裏是源代碼

using System; 

using System.Collections.Generic; 
using System.Text; 
using System.Net.Sockets; 
using System.Net; 
using System.Threading; 
using System.Diagnostics; 

namespace SmartDevice_Server 
{ 
    /// <summary> 
    /// ClientConnection saves connection information is used to keep context in Async and Event calls 
    /// </summary> 
    /// <param name="networkStream"> NetworkStream Object of TCPClient</param> 
    /// <param name="data">Byte array that serves as Buffer</param> 
    /// <returns></returns> 
    public class ClientConnection : EventArgs 
    { 
     public NetworkStream NetworkStream { get; private set; } 
     public byte[] Data { get; private set; } 
     public int byteReadCount { get; set; } 

     public ClientConnection(NetworkStream networkStream, byte[] data) 
     { 
      NetworkStream = networkStream; 
      Data = data; 
     } 
    } 

    /// <summary> 
    /// MySocket - Is a server that listens for events and triggers Events upon Request Completion 
    /// </summary> 
    public class MySocketTCP 
    { 
     #region Members 
     TcpListener myTcpListener; 
     TcpClient myTcpClient; 
     NetworkStream myNetworkStream; 

     const string localHost = "127.0.0.1"; 
     IPAddress myAddress = IPAddress.Parse(localHost); 
     int myPortNumber = 58889; 
     byte[] myData; 

     int bytesReadCount; 
     const int MIN_REQUEST_STRING_SIZE = 10; 

     int TimeStart; 

     //Event Setup 
     public event socketReadCompleteHandler socketReadCompleteEvent; 
     public EventArgs eventArguments = null; 
     public delegate void socketReadCompleteHandler(MySocketTCP myTcpSocket, ClientConnection eventArguments); 

     //BufferSize 
     public const int myBufferSize = 300000; 

     #endregion 

     //Constructor 
     /// <summary> 
     /// MySocketTCP Constructor 
     /// NOTE: By default connects to local host (127.0.0.1:58889) 
     /// </summary> 
     /// <returns></returns> 
     public MySocketTCP() 
     { 
      Init(); 
     } 

     /// <summary> 
     /// Constructor overloaded to receive IPAdress Host, and Port number 
     /// </summary> 
     /// <param name="hostAddress">IPAdress that represent an IP address</param> 
     /// <param name="portNumber">Integer that represents the port number</param> 
     /// <returns></returns> 
     public MySocketTCP(IPAddress hostAddress, int portNumber) 
     { 
      myAddress = hostAddress; 
      myPortNumber = portNumber; 

      Init(); 
     } 

     /// <summary> 
     /// Initializes the TCPListner with address, and port number 
     /// </summary> 
     /// <returns></returns> 
     public void Init() 
     { 
      try 
      { 
       myTcpListener = new TcpListener(myAddress, myPortNumber); 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 
     } 

     /// <summary> 
     /// Listens Asynchronously to Clients, class a recieveMessageHandler to process the read 
     /// 
     /// * TODO_Listener_Timer: After you accept a connection you wait for data to be Read indefinitely 
     /// Possible solution: Use a timeout to close the socket connection. 
     /// Check WIKI, TODOS 
     /// </summary> 
     /// <returns></returns> 
     public void ListenAsync() 
     { 
      myTcpListener.Start(); 

      while (true) 
      { 
       //blocks until a client has connected to the server 
       myTcpClient = myTcpListener.AcceptTcpClient(); 
       //myTcpClient.ReceiveBufferSize = 300000; 


       var client = new ClientConnection(myTcpClient.GetStream(), new byte[myTcpClient.ReceiveBufferSize]); 

       // Capture the specific client and pass it to the receive handler 
       client.NetworkStream.BeginRead(client.Data, 0, client.Data.Length, r => receiveMessageHandler(r, client), null); 
      } 
     } 

     /// <summary> 
     /// Callback is used to read the request Asynchronously, triggers socketReadCompleteEvent 
     /// </summary> 
     /// <param name="asyncResult"></param> 
     /// <param name="clientInstance"></param> 
     /// <returns></returns> 
     public void receiveMessageHandler(IAsyncResult asyncResult, ClientConnection clientInstance) 
     { 
      bytesReadCount = 0; 

      lock (clientInstance.NetworkStream) 
      { 
       try 
       { 
        bytesReadCount = clientInstance.NetworkStream.EndRead(asyncResult); 
        clientInstance.byteReadCount = bytesReadCount; 
       } 
       catch (System.IO.IOException ioexcp) 
       { 
        Debug.WriteLine(ioexcp.ToString()); 
       } 
       catch (System.ObjectDisposedException objdispexc) 
       { 
        Debug.WriteLine(objdispexc.ToString()); 
       } 
       catch (Exception excp) 
       { 
        Debug.WriteLine(excp.ToString()); 
       } 
      } 

      if (bytesReadCount < MIN_REQUEST_STRING_SIZE) 
      { 
       //Could not read form client. 
       Debug.WriteLine("NO DATA READ. Close Connection"); 
       //If there is no data then close connection. 

       //clientInstance.NetworkStream.Close(); 
      } 
      else 
      { 
       if (socketReadCompleteEvent != null) 
       { 
        socketReadCompleteEvent(this, clientInstance); 
       } 
      } 
     } 


     /// <summary> 
     /// Reads the request, uses the ClientConnection for context 
     /// </summary> 
     /// <param name="connObj">Connection object contains the NetworkStream, 
     /// Data Buffer, and Number of bytes read.</param> 
     /// <returns></returns> 
     public string ReadAsync(ClientConnection connObj) 
     { 
      int bytesReadCount = connObj.byteReadCount; 
      byte[] myData = connObj.Data; 

      string xmlMessage; 

      try 
      { 
       xmlMessage = Encoding.ASCII.GetString(myData, 0, bytesReadCount); 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 

      return xmlMessage; 
     } 

     /// <summary> 
     /// Is used to send/write the message to the correct socket 
     /// Closes the connection. 
     /// </summary> 
     /// <param name="connObj">context object</param> 
     /// <param name="outMessage">message to send</param> 
     /// <returns></returns> 
     public void WriteAsync(ClientConnection connObj, string outMessage) 
     { 
      const int timeDivisor = 10000; 
      byte[] outBytes = Encoding.ASCII.GetBytes(outMessage); 

      try 
      { 
       Delay(outBytes.Length/timeDivisor); 
       connObj.NetworkStream.Write(outBytes, 0, outBytes.Length); 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 

      //TODO_5254: Closes the connection, check MoSync side. 
      //try 
      //{ 
      // connObj.NetworkStream.Close(); 
      //} 
      //catch (Exception ex) 
      //{ 
      // throw ex; 
      //} 

      int TimeEnd = Environment.TickCount; 
      int TimeResult = TimeEnd - TimeStart; 
     } 

     /// <summary> 
     /// Closes TCPClient 
     /// Warning: Does not close the underlying connection. 
     /// </summary> 
     /// <returns></returns> 
     public void Close() 
     { 
      try 
      { 

       myTcpClient.Close(); 
      } 
      catch (Exception ex) 
      {  
       throw ex; 
      } 
     } 

     /// <summary> 
     /// Helper Function creates timeouts and delays. 
     /// </summary> 
     /// <param name="ms"></param> 
     /// <returns></returns> 
     private void Delay(int ms) 
     { 
      int time = Environment.TickCount; 

      do 
      { 
       if (Environment.TickCount - time >= ms) return; 
      } while (true); 
     } 
    } 
} 

更新:

try 
       { 
        bytesReadCount = clientInstance.NetworkStream.EndRead(asyncResult); 
        clientInstance.stringBuilder.Append(Encoding.ASCII.GetString(clientInstance.Data, 0, bytesReadCount)); 
        //If buffer is bigger than myTcpClient.ReceiveBufferSize 
        while (clientInstance.NetworkStream.DataAvailable) 
        { 
         Debug.WriteLine("More data to read..."); 
         //clientInstance.NetworkStream.EndRead(asyncResult); 
         int chuckByteSize = clientInstance.NetworkStream.Read(clientInstance.Data, 0, myTcpClient.ReceiveBufferSize); 
         bytesReadCount += chuckByteSize; 
         //string textReceived = Encoding.ASCII.GetString(clientInstance.Data, 0, chuckByteSize); 
         clientInstance.stringBuilder.Append(Encoding.ASCII.GetString(clientInstance.Data, 0, chuckByteSize)); 
         //BP - Ver Data 
        } 
        clientInstance.byteReadCount = bytesReadCount; 
        //string sbString = clientInstance.sb.ToString(); 
        //int sizeString = sbString.Length; 
       } 
       catch (System.IO.IOException ioexcp) 
       { 
        Debug.WriteLine(ioexcp.ToString()); 
       } 
       catch (System.ObjectDisposedException objdispexc) 
       { 
        Debug.WriteLine(objdispexc.ToString()); 
       } 
       catch (Exception excp) 
       { 
        Debug.WriteLine(excp.ToString()); 
       } 
      } 
+0

我以爲'TcpListener.Server.RecieveBufferSize'是由網絡決定的 - 沒有設置爲任何聽起來不錯的東西。 – jp2code

回答

0

這不是100%清楚根據你的問題,你的意思是50,000或50萬件(代碼和文本別t同意)。

The documentation indicatessetsockoptSOL_SOCKETSO_RCVBUF應該是有效的OS,雖然它可能是你在平臺上不允許這樣做。

這就是說,我已經將超過50k(甚至500k)的數據傳輸的數量比沒有問題的套接字大得多,我從來沒有設置過這個屬性。你有使用它的具體原因嗎?如果你忽略它,我希望使用套接字的調用仍然有效。

+0

我想通過套接字連接localhost傳輸500.000字節。我有一個C++客戶端發送數據,我只收到32768,只能發送〜16K。我想我可能需要創建一個bufferManager,但我也需要正確地處理對象,因爲我的線程正在關閉,並且有時會拋出異常: 線程0xe612268a已退出,並且代碼爲0(0x0)。 System.dll中發生類型'System.ObjectDisposedException'的第一次機會異常 如果我在桌面版本上設置此值,則可以發送該數量的數據。 – Astronaut

+0

我敢打賭,'bytesReadCount'!='client.Data.Length'。你不能假設你一次就能得到所有的數據,你需要繼續接收,直到你達到預期的長度(你的接收回調應該再次調用接收) – ctacke

+0

我的問題在於,可以同時完成多個請求......所以我如何控制正在完成的請求?這是我不知道正在完成的請求的大小。 – Astronaut