首页 > 解决方案 > C# 通过套接字发送字节数组

问题描述

我一直在尝试将字节数组从客户端发送到服务器以构建身份验证服务器。

我已经使用 Microsoft 异步服务器套接字示例成功发送了字节数组。链接 但是在他们的示例中,他们使用字符串来指示字节传输的结束。

content.IndexOf("<EOF>") > -1

我不喜欢这种方法并将其删除,因此服务器一直等待来自客户端的消息,直到客户端或服务器数据包处理程序决定关闭套接字。

我不明白需要一个字符串来指示 transfer 的结束。我可以通过数组长度检查这个吗? 我使用的方法是否足够安全以确保数据完整性?

我的代码服务器端:在方法中进行了更改:ReadCallback

public class AsynchronousSocketListener
{
    // Thread signal.  
    public static ManualResetEvent allDone = new ManualResetEvent(false);

    public AsynchronousSocketListener()
    {
    }

    public static void StartListening(String hostname, int port)
    {
        // Establish the local endpoint for the socket.  
        // The DNS name of the computer  
        // example running the listener is "localhost".  
        IPHostEntry ipHostInfo = Dns.GetHostEntry(hostname);
        IPAddress ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);

        // Create a TCP/IP socket.  
        Socket listener = new Socket(ipAddress.AddressFamily,
            SocketType.Stream, ProtocolType.Tcp);

        try
        {
            // Bind the socket to the local endpoint and listen for incoming connections.  
            listener.Bind(localEndPoint);
            listener.Listen(100);

            // Do not stop after one connection
            while (true)
            {
                // Set the event to nonsignaled state.  
                allDone.Reset();

                // Start an asynchronous socket to listen for connections.  
                Console.WriteLine("Listening for new connection");
                listener.BeginAccept(
                    new AsyncCallback(AcceptCallback),
                    listener);

                // Wait until a connection is made before listening again
                // for a new connection.  
                allDone.WaitOne();
                Console.WriteLine("Connection established.");

            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }

        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();

    }

    public static void AcceptCallback(IAsyncResult ar)
    {
        // Signal the main thread to continue.  
        allDone.Set();

        // Get the socket that handles the client request.  
        Socket listener = (Socket)ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        // Create the state object.  
        StateObject state = new StateObject();
        state.workSocket = handler;
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReadCallback), state);
    }

    public static void ReadCallback(IAsyncResult ar)
    {
        String content = String.Empty;

        // Retrieve the state object and the handler socket  
        // from the asynchronous state object.  
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;

        // Read data from the client socket.
        //int bytesRead = handler.EndReceive(ar);

        // New way, handles forcibly disconnect.
        SocketError errorCode;
        int bytesRead = 0;
        try
        {
            bytesRead = handler.EndReceive(ar, out errorCode);

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }

        if (bytesRead > 0)
        {
            // There  might be more data, so store the data received so far.  
            state.sb.Append(Encoding.ASCII.GetString(
                state.buffer, 0, bytesRead));

            PacketHandler.CheckPacket(
                handler: handler,
                data:  state.buffer,
                length: bytesRead
                );

            // Check for end-of-file tag. If it is not there, read
            // more data.  
            content = state.sb.ToString();

            Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
            content.Length, content);


            // Keep listening to the socket for messages while the socket is connected.
            if (handler.Connected)
            {
                // Empty the previous message
                state.sb.Clear();

                try
                {
                    // Recursieve? Calling itself til socket is disposed off.
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReadCallback), state);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Thread.Sleep(1000);

            }

            // If it got this far, means socket is closed. Double checking before disposing of the socket.
            if (!handler.Connected)
            {

                try
                {
                    // https://stackoverflow.com/questions/4160347/close-vs-shutdown-socket
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                    Console.WriteLine("Closed socket");

                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed close socket. " + ex.Message);
                }
            }



            //if (content.IndexOf("<EOF>") > -1)
            //{
            //    // All the data has been read from the
            //    // client. Display it on the console.  
            //    Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
            //        content.Length, content);
            //    // Echo the data back to the client.  
            //    Send(handler, content);
            //}
            //else
            //{
            //    // Not all data received. Get more.  
            //    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            //    new AsyncCallback(ReadCallback), state);
            //}
        }
    }

    public static void Send(Socket handler, String data)
    {
        // Convert the string data to byte data using ASCII encoding.  
        byte[] byteData = Encoding.ASCII.GetBytes(data);

        // Begin sending the data to the remote device.  
        handler.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), handler);
    }

    private static void SendCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.  
            Socket handler = (Socket)ar.AsyncState;

            // Complete sending the data to the remote device.  
            int bytesSent = handler.EndSend(ar);
            Console.WriteLine("Sent {0} bytes to client.", bytesSent);

            handler.Shutdown(SocketShutdown.Both);
            handler.Close();

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
}

标签: c#.netsocketsnetwork-programming

解决方案


推荐阅读