none
Асинхронный клиент/сервер RRS feed

  • Вопрос

  • За основу взял пример с msdn, убрал из сервера принятие сообщений, а из клиента отправку, и вместо строки передается массив байт, все это в таймерах на минимальных задержках в вин формах.

    Все работает но не долго, в методе Receive на клиенте возникает исключение,

    "System.Net.Sockets.SocketException: "Запрос на отправку или получение данных  (when sending on a datagram socket using a sendto call) no address was supplied""

    клиент

    using System;
    using System.Diagnostics;
    using System.Drawing;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace Client
    {
        public partial class Client : Form
        {
            public Client()
            {
                InitializeComponent();
            }
            Stopwatch stopWatch = new Stopwatch();
            static ManualResetEvent connectDone = new ManualResetEvent(false);
            static ManualResetEvent receiveDone = new ManualResetEvent(false);
    
            private void Client_Load(object sender, EventArgs e)
            {
                timer1.Start();
            }
            private void StartClient()
            {
                IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
                IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);
                Socket client = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
                connectDone.WaitOne();
                Receive(client);
                receiveDone.WaitOne();
                //client.Shutdown(SocketShutdown.Both);
                //client.Close();
            }
            private static void ConnectCallback(IAsyncResult ar)
            {
                Socket client = (Socket)ar.AsyncState;
                client.EndConnect(ar);
                client.RemoteEndPoint.ToString();
                connectDone.Set();
            }
            public class StateObject
            {
                public Socket workSocket = null;
                public byte[] buffer = new byte[300000];
            }
            private void Receive(Socket client)
            {
                StateObject state = new StateObject();
                state.workSocket = client;
                client.BeginReceive(state.buffer, 0, state.buffer.Length, 0, new AsyncCallback(ReceiveCallback), state);
            }
            private void ReceiveCallback(IAsyncResult ar)
            {
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;
                int bytesRead = client.EndReceive(ar);
                if (bytesRead > 0)
                {
                    client.BeginReceive(state.buffer, 0, state.buffer.Length, 0, new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    if (state.buffer.Length > 1)
                    {
                        using (MemoryStream ms = new MemoryStream(state.buffer))
                            pictureBox1.Image = Image.FromStream(ms);
                    }
                    receiveDone.Set();
                }
            }
            private void Timer1_Tick(object sender, EventArgs e)
            {
                this.Text = stopWatch.ElapsedMilliseconds.ToString();
                stopWatch.Reset();
                StartClient();
                stopWatch.Start();
            }
        }
    }
    сервер
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace Server
    {
        public partial class Server : Form
        {
            public Server()
            {
                InitializeComponent();
            }
            static ManualResetEvent allDone = new ManualResetEvent(false);
            public void StartListening()
            {
                IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
                IPEndPoint localEP = new IPEndPoint(ipHostInfo.AddressList[0], 11000);
                Socket listener = new Socket(localEP.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                listener.Bind(localEP);
                listener.Listen(10);
                while (true)
                {
                    allDone.Reset();
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                    allDone.WaitOne();
                }
            }
            public static void AcceptCallback(IAsyncResult ar)
            {
                allDone.Set(); 
                Socket listener = (Socket)ar.AsyncState;
                Socket handler = listener.EndAccept(ar);
                StateObject state = new StateObject();
                state.workSocket = handler;
                using (MemoryStream ms = new MemoryStream())
                {
                    ImageFromScreen().Save(ms, ImageFormat.Jpeg);
                    Send(handler, ms.ToArray());
                }
            }
            private static void Send(Socket handler, byte[] byteData)
            {
                handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
            }
            private static void SendCallback(IAsyncResult ar)
            {
                Socket handler = (Socket)ar.AsyncState; 
                handler.EndSend(ar);
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
            }
            public class StateObject
            {
                public Socket workSocket = null;
            }
            public static Bitmap ImageFromScreen()
            {
                Rectangle screenSize = Screen.PrimaryScreen.Bounds;
                Bitmap target = new Bitmap(screenSize.Width, screenSize.Height);
                using (Graphics g = Graphics.FromImage(target))
                    g.CopyFromScreen(0, 0, 0, 0, new Size(screenSize.Width, screenSize.Height));
                return target;
            }
            private void Timer1_Tick(object sender, EventArgs e)
            {
                StartListening();
            }
            private void Button1_Click(object sender, EventArgs e)
            {
                label1.Text = "online";      
                timer1.Start();
            }
        }
    }

    22 сентября 2019 г. 17:03