Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有二进制/字节[]流的SocketAsyncEventArgs_C#_Sockets_Stream_Socketasynceventargs - Fatal编程技术网

C# 具有二进制/字节[]流的SocketAsyncEventArgs

C# 具有二进制/字节[]流的SocketAsyncEventArgs,c#,sockets,stream,socketasynceventargs,C#,Sockets,Stream,Socketasynceventargs,我是C#and sockets的新手,如果我的问题不符合要求,我道歉。我开始使用此链接中的示例构建套接字接口: 我希望能够通过套接字传输二进制文件,因此我假设(可能是错误的)我不应该使用StringBuilder。我将原始的OSUserToken更改为使用MemoryStream和BinaryWriter(注释原始代码) 在代码的其他地方(从上面的链接),SocketAsyncEventArgs使用SetBuffer(新字节[\u bufferSize],0,\u bufferSize)初始化

我是C#and sockets的新手,如果我的问题不符合要求,我道歉。我开始使用此链接中的示例构建套接字接口:

我希望能够通过套接字传输二进制文件,因此我假设(可能是错误的)我不应该使用
StringBuilder
。我将原始的
OSUserToken
更改为使用
MemoryStream
BinaryWriter
(注释原始代码)

在代码的其他地方(从上面的链接),
SocketAsyncEventArgs
使用
SetBuffer(新字节[\u bufferSize],0,\u bufferSize)初始化。我担心这会与我的
MemoryStream
BinaryWriter
不匹配,但它似乎可以工作

sealed class UserToken : IDisposable
{
    private Socket _ownerSocket;
    public Socket ownerSocket { get { return _ownerSocket; } }

    private MemoryStream _memoryStream;
    private BinaryWriter _binaryWriter;
    //private StringBuilder stringbuilder;

    private int totalByteCount;

    public String LastError;

    public UserToken(Socket readSocket, int bufferSize)
    {
        _ownerSocket = readSocket;
        _memoryStream = new MemoryStream();
        _binaryWriter = new BinaryWriter(_memoryStream);
        //stringbuilder = new StringBuilder(bufferSize);
    }

    // Do something with the received data, then reset the token for use by another connection.
    // This is called when all of the data have been received for a read socket.
    public void ProcessData(SocketAsyncEventArgs args)
    {
        String received = System.Text.Encoding.ASCII.GetString(_memoryStream.ToArray());
        //String received = stringbuilder.ToString();

        Debug.Write("Received: \"" + received + "\". The server has read " + received.Length + " bytes.");

        _memoryStream.SetLength(0);
        //stringbuilder.Length = 0;
        totalByteCount = 0;
    }

    public bool ReadSocketData(SocketAsyncEventArgs readSocket)
    {
        int byteCount = readSocket.BytesTransferred;

        /*
        if ((totalByteCount + byteCount) > stringbuilder.Capacity)
        {
            LastError = "Receive Buffer cannot hold the entire message for this connection.";
            return false;
        }
        else
        {
        */
            //stringbuilder.Append(Encoding.ASCII.GetString(readSocket.Buffer, readSocket.Offset, byteCount));
            _binaryWriter.Write(readSocket.Buffer,readSocket.Offset,byteCount);
            totalByteCount += byteCount;
            return true;
        /*}*/
    }

    public void Dispose()
    {
        _memoryStream.Dispose();
        _binaryWriter.Dispose();
        try
        {
            _ownerSocket.Shutdown(SocketShutdown.Both);
        }
        catch
        {
            //Nothing to do here, connection is closed already
        }
        finally
        {
            _ownerSocket.Close();
        }
    }
}
当我运行这个时,它似乎可以正常工作。即使我将
protected const int DEFAULT\u BUFFER\u SIZE=1
设置为默认值,它也会接受大于1字节的流:

17:11:20:433 - Debug - Initializing the listener on port 5000...
17:11:20:439 - Debug - Starting the listener...
17:11:20:444 - Debug - Server started.
17:11:31:856 - Debug - Received: "listener". The server has read 8 bytes.
17:11:33:264 - Debug - Received: "l". The server has read 1 bytes.
17:11:33:268 - Debug - Received: "istener". The server has read 7 bytes.
17:11:36:744 - Debug - Received: "l". The server has read 1 bytes.
17:11:36:744 - Debug - Received: "i". The server has read 1 bytes.
17:11:36:746 - Debug - Received: "stener". The server has read 6 bytes.
我的问题是:

  • 我认为
    StringBuilder
    不适用于二进制文件,我应该使用
    MemoryStream
    BinaryWriter
  • 如果在程序的其他地方,
    SocketAsyncEventArgs
    SetBuffer(新字节[\u bufferSize],0,\u bufferSize)初始化,我是否需要担心缓冲区溢出
  • 如果必须遵守缓冲区大小限制,是否需要对发送数据的客户端设置相同的缓冲区限制

  • 我找到了问题的答案

  • StringBuilder
    工作正常。只需在发送前对
    base64
    中的字符串进行编码,并在接收后进行解码。无论是发送文本还是二进制数据,都应该这样做。请看我在下面写的课程
  • 仍然不知道这个问题的答案,但将其视为
    StringBuilder
    &
    base64
    使用二进制,这个问题不再相关
  • 我认为这个问题的答案是肯定的。客户端应具有最大消息长度。我根据套接字的头部分进行控制,我在头部分定义消息的长度。头是固定长度的,我的最大消息长度是
    0xFFFFF
  • 用于编码/解码base64的类:

    public static class Base64
    {
        public static string EncodeBase64(string text)
        {
            return System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(text));
        }
    
        public static string EncodeBase64(byte[] array)
        {
            return System.Convert.ToBase64String(array);
        }
    
        public static string DecodeBase64ToString(string base64String)
        {
            return System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(base64String));
        }
    
        public static Byte[] DecodeBase64ToBinary(string base64String)
        {
            Byte[] bytes = System.Convert.FromBase64String(base64String);
            return bytes;
        }
    }