Socket udp 发送接收问题

时间:2021-05-28 20:43:58
发送接收有问题,请大牛分析一下
客户端:
  public partial class FClient : Form
    {
        public FClient()
        {
            InitializeComponent();
        }

        Socket m_Socket;
        Thread m_Thread;

        private void Form1_Load(object sender, EventArgs e)
        {
            Statement();
        }

        /// <summary>
        /// 声明
        /// </summary>
        public void Statement()
        {
            m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
           
            m_Thread = new Thread(new ThreadStart(GetImage));
            m_Thread.IsBackground = true;
            m_Thread.Start();
        }


        public void GetImage()
        {
            while (true)
            {
                //获得当前屏幕的分辨率 
                Screen scr = Screen.PrimaryScreen;
                Rectangle rc = scr.Bounds; 
                int iWidth = rc.Width; 
                int iHeight = rc.Height;
                //创建一个和屏幕一样大的Bitmap 
                Image MyImage = new Bitmap(iWidth, iHeight);                  
                //从一个继承自Image类的对象中创建Graphics对象             
                Graphics g = Graphics.FromImage(MyImage);                 
                //抓屏并拷贝到myimage里 
                g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(iWidth, iHeight));

                MemoryStream stream = new MemoryStream();
                MyImage.Save(stream, ImageFormat.Jpeg);

                byte[] buffImage = stream.GetBuffer();
                IPEndPoint receivePoint = new IPEndPoint(IPAddress.Parse("192.168.1.5"), 8000);
                m_Socket.BeginSendTo(buffImage, 0, buffImage.Length, SocketFlags.None, receivePoint, SendData, m_Socket);
               
                Thread.Sleep(1000);
            }
        }

        private void SendData(IAsyncResult ar)
        {
            Socket socket = (Socket)ar.AsyncState;
            try
            {
                socket.EndSendTo(ar);
            }
            catch (Exception ex)
            {
               
            }
        }
    }



服务器端:
 public partial class FServer : Form
    {
        public FServer()
        {
            InitializeComponent();
        }

        Socket m_Socket;
        Thread m_Thread;
        private byte[] m_ByteImg = new byte[2 * 1024 * 1024]; //接受图片的缓冲

        private void Form1_Load(object sender, EventArgs e)
        {
            Statement();
        }

        /// <summary>
        /// 声明
        /// </summary>
        public void Statement()
        {
            m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            uint IOC_IN = 0x80000000;
            uint IOC_VENDOR = 0x18000000;
            uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
            //m_Socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
            IPEndPoint receivePoint = new IPEndPoint(IPAddress.Parse("192.168.1.5"), 4500);
            m_Socket.Bind(receivePoint);
            m_Thread = new Thread(new ThreadStart(Listener));
            m_Thread.IsBackground = true;
            m_Thread.Start();
        }


        /// <summary>
        /// 监听
        /// </summary>
        private void Listener()
        {
            while (true)
            {
                //每隔5000微妙查询一次socket状态
                if (m_Socket.Poll(5000, SelectMode.SelectRead))//为可读时,读取
                {
                    m_Socket.BeginReceive(m_ByteImg, 0, m_ByteImg.Length, SocketFlags.None, ReceiveData, m_Socket);
                }
            }
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="ar"></param>
        private void ReceiveData(IAsyncResult ar)
        {
            Socket socketTemp = (Socket)ar.AsyncState;
            int count = socketTemp.EndReceive(ar);
            if (count > 0)
            {
                byte[] buff = new byte[count];
                Buffer.BlockCopy(m_ByteImg, 0, buff, 0, count);
                MemoryStream memoryStream = new MemoryStream(buff);
                Bitmap bitmap = (Bitmap)System.Drawing.Image.FromStream(memoryStream);
                pictureBox1.Image = bitmap;
            }
        }
    }

12 个解决方案

#1


引用 楼主 qi383943715 的回复:
            try
            {
                socket.EndSendTo(ar);
            }
            catch (Exception ex)
            {
               // 你不检查错误?
            }

UDP的每帧的 大小不能超过64K

#2


应该说64k还是理想值。取决于网络的MTU设置,UDP每包 往往不能超过1500字节

#3


IPEndPoint receivePoint = new IPEndPoint(IPAddress.Parse("192.168.1.5"), 8000);
你把这东西写到while循环里是想干啥

#4


现在是客户端发送,但服务端总是接收不到

#5


1.服务器端开侦听了吗
2.侦听的端口跟你客户端发送的端口一致吗?

服务器端侦听4500,客户端往8000发,能收到才有鬼
而且只是bind,好像没调用.Listen啊

#6


引用 1 楼 Forty2 的回复:
Quote: 引用 楼主 qi383943715 的回复:

            try
            {
                socket.EndSendTo(ar);
            }
            catch (Exception ex)
            {
               // 你不检查错误?
            }

UDP的每帧的 大小不能超过64K


报错,一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或该用户用于接收数据报的缓冲区比数据报小。
应该怎么处理?

#7


而且客户端没使用connect方法,直接就send,不报错?
你只定义了从端口8000往外发,发给谁呀

#8


建议还是上网找例子,哪怕是TCP的,也可以拿来好好参考参考
UDP和TCP差不多的,就是socket参数不一样而已

不要凭想象瞎写

#9


UDP的connect和TCP的connect不同
TCP在connect的时候就执行3次握手,如果对方没有开侦听,直接就报错了
而UDP在connect的时候,只是指定要发给什么IP的什么端口,不执行握手

#10


引用 6 楼 qi383943715 的回复:
应该怎么处理?


你的数据量用UDP一包发不出去。而UDP分包的话很麻烦,因为UDP不保证顺序,可能丢包,你接收端却要求完整拼包才能正常工作。

你可以用TCP做。或用其他协议,比如RTSP等等。

#11


udp 不需要connect,只要bind 即可

#12


可以参考下 CSR-Socket 实现异步收发 下载地址 http://download.csdn.net/detail/laizhiping_rj/7903997

#1


引用 楼主 qi383943715 的回复:
            try
            {
                socket.EndSendTo(ar);
            }
            catch (Exception ex)
            {
               // 你不检查错误?
            }

UDP的每帧的 大小不能超过64K

#2


应该说64k还是理想值。取决于网络的MTU设置,UDP每包 往往不能超过1500字节

#3


IPEndPoint receivePoint = new IPEndPoint(IPAddress.Parse("192.168.1.5"), 8000);
你把这东西写到while循环里是想干啥

#4


现在是客户端发送,但服务端总是接收不到

#5


1.服务器端开侦听了吗
2.侦听的端口跟你客户端发送的端口一致吗?

服务器端侦听4500,客户端往8000发,能收到才有鬼
而且只是bind,好像没调用.Listen啊

#6


引用 1 楼 Forty2 的回复:
Quote: 引用 楼主 qi383943715 的回复:

            try
            {
                socket.EndSendTo(ar);
            }
            catch (Exception ex)
            {
               // 你不检查错误?
            }

UDP的每帧的 大小不能超过64K


报错,一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或该用户用于接收数据报的缓冲区比数据报小。
应该怎么处理?

#7


而且客户端没使用connect方法,直接就send,不报错?
你只定义了从端口8000往外发,发给谁呀

#8


建议还是上网找例子,哪怕是TCP的,也可以拿来好好参考参考
UDP和TCP差不多的,就是socket参数不一样而已

不要凭想象瞎写

#9


UDP的connect和TCP的connect不同
TCP在connect的时候就执行3次握手,如果对方没有开侦听,直接就报错了
而UDP在connect的时候,只是指定要发给什么IP的什么端口,不执行握手

#10


引用 6 楼 qi383943715 的回复:
应该怎么处理?


你的数据量用UDP一包发不出去。而UDP分包的话很麻烦,因为UDP不保证顺序,可能丢包,你接收端却要求完整拼包才能正常工作。

你可以用TCP做。或用其他协议,比如RTSP等等。

#11


udp 不需要connect,只要bind 即可

#12


可以参考下 CSR-Socket 实现异步收发 下载地址 http://download.csdn.net/detail/laizhiping_rj/7903997