如何使用套接字编程(TCP)从服务器向客户端发送两个图像?

时间:2019-05-15 09:27:38

标签: c# socket.io

我想将一些图像从服务器发送到客户端。我想当用户连接到服务器并请求图像时,我向其中发送了一些图像。我进行了搜索,但是所有有关从客户端到服务器而不是服务器到客户端发送一个图像的答案! 我编写了以下代码,用于从服务器向客户端发送一个图像,但由于运行时关闭套接字,然后调用了“ SendCallback”方法,因此在运行时出现错误。我在哪里关闭并关闭插座?

  public class ImageSocketServer
{
    public class StateObject
    {
        // Client socket.
        public Socket WorkSocket = null;
        // Size of receive buffer.
        public const int BufferSize = 256;
        // Receive buffer.
        public byte[] Buffer = new byte[BufferSize];
        // Received data string.
        public StringBuilder sb = new StringBuilder();
    }

    public ManualResetEvent AllDone = new ManualResetEvent(false);
    private static ManualResetEvent sendDone = new ManualResetEvent(false);

    private Socket handler;

    public void StartListening(string ip, int port)
    {
        IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(ip), port);
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        listener.Bind(serverEndPoint);
        listener.Listen(port);

        while (true)
        {
            AllDone.Reset();

            listener.BeginAccept(AcceptCallback, listener);

            AllDone.WaitOne();
        }
    }

    private void AcceptCallback(IAsyncResult asyncResult)
    {
        AllDone.Set();
        Socket listener = (Socket)asyncResult.AsyncState;
        Socket handler = listener.EndAccept(asyncResult);
        StateObject state = new StateObject { WorkSocket = handler };
        handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0,
            ReadCallback, state);


    }

    private void ReadCallback(IAsyncResult asyncResult)
    {
        string content = string.Empty;

        StateObject state = (StateObject)asyncResult.AsyncState;
         handler = state.WorkSocket;

        int bytesRead = handler.EndReceive(asyncResult);

        if (bytesRead > 0)
        {
            state.sb.Append(Encoding.UTF8.GetString(state.Buffer, 0, bytesRead));
            content = state.sb.ToString();
            if (content.IndexOf(Cache.EndOfMessage, StringComparison.Ordinal) > -1)
            {
                //Send(handler, @"C:\Users\f.hashemian\Pictures\Camera Roll\test.jpg");
                SendImage(handler, @"C:\Users\f.hashemian\Pictures\Camera Roll\test.jpg");

                //

            }
            else
            {
                handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
            }
        }
    }

    private  void SendImage(Socket client, string imagePath)
    {
        byte[] imgBuff = File.ReadAllBytes(imagePath);
        var length = imgBuff.Length;

        Send(client, BitConverter.GetBytes(length));
        sendDone.WaitOne();
        Send(client, imgBuff);
        sendDone.WaitOne();


        //Here close connection and i have error in SendCallback
        handler.Shutdown(SocketShutdown.Both);
        handler.Close();

    }

    private  void Send(Socket client, byte[] byteData)
    {
        // Begin sending the data to the remote device.
        client.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), client);
    }

    private void SendCallback(IAsyncResult asyncResult)
    {
        try
        {
            Socket handler = (Socket)asyncResult.AsyncState;
            int byteSent = handler.EndSend(asyncResult);

            sendDone.Set();


            //

        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

}

这是关于发送一张具有发送图像尺寸的图像,然后将图像发送到客户端。如果您有关于某些图像的任何教程,请在此处发送链接

1 个答案:

答案 0 :(得分:0)

根据MSDN文档https://docs.microsoft.com/en-us/dotnet/api/system.threading.manualresetevent.set?view=netframework-1.1#System_Threading_ManualResetEvent_Set,应在ManualResetEvent上调用WaitOne()以将其设置为非信号状态后,再调用Reset()方法。

private  void SendImage(Socket client, string imagePath)
{
    byte[] imgBuff = File.ReadAllBytes(imagePath);
    var length = imgBuff.Length;

    Send(client, BitConverter.GetBytes(length));
    sendDone.WaitOne();
    sendDone.Reset();
    Send(client, imgBuff);
    sendDone.WaitOne();
    sendDone.Reset();


    //Here close connection and i have error in SendCallback
    handler.Shutdown(SocketShutdown.Both);
    handler.Close();

}

否则,将跳过第二个WaitOne()(因为事件处于信号状态),并将调用Shutdown()方法。如此一来,您将在SendCallback中收到异常,因为该连接已经关闭。对于您来说,最好使用AutoResetEvent https://docs.microsoft.com/en-us/dotnet/api/system.threading.autoresetevent?view=netframework-4.8,它会在释放单个等待线程后自动重置。