首页 新闻 会员 周边 捐助

C#中异步Socket中EndReceive报远程主机强迫关闭了一个现有的连接问题

0
[已解决问题] 解决于 2016-04-13 10:22

有两个问题如下
第一个问题,我足足等了2分钟,ReceiveCallback里的断点才进去,怎么会等这么长时间
第二个问题,ServerSocket 中的EndReceive报“远程主机强迫关闭了一个现有的连接”这个错误
调试截图如下






ClientSocket 中的Program.cs代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace SendTest
{
    public class StateObject
    {
        public Socket workSocket = null;
        public const int BUFFER_SIZE = 1024;
        public byte[] buffer = new byte[BUFFER_SIZE];
        public StringBuilder sb = new StringBuilder();
    }

    class Program
    {
        static Socket clientSocket;
        static void Main(string[] args)
        {
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 8081)); //配置服务器IP与端口
                Console.WriteLine("连接服务器成功");
            }
            catch
            {
                Console.WriteLine("连接服务器失败,请按回车键退出!");
                return;
            }
            Send();
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        private static void  Send()
        {
            if (clientSocket != null)
            {
                try
                {
                    byte[] byteData = Encoding.UTF8.GetBytes("我是客户端,寻求帮助");
                    clientSocket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientSocket);
                    Console.WriteLine("BeginSend 执行完毕");
                    Console.ReadLine();
                }
                catch (Exception ex)
                { 
                    
                }
            }
        }

        /// <summary>
        /// 发送消息回掉函数
        /// </summary>
        /// <param name="ar"></param>
        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                if (client != null)
                {
                    int bytesSent = client.EndSend(ar);
                }
            }
            catch (Exception ex)
            {

            }
        }
    }
}

ServerSocket 中的Program.cs代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ReceiveTest
{
    class Program
    {
        static Socket clientSocket;
        static void Main(string[] args)
        {
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 8081)); //配置服务器IP与端口
                Console.WriteLine("连接服务器成功");
            }
            catch
            {
                Console.WriteLine("连接服务器失败,请按回车键退出!");
                return;
            }

            Thread myThread = new Thread(Receive);
            myThread.Start();
            Console.ReadLine();
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        private static void Receive()
        {
            if (clientSocket != null)
            {
                try 
                {
                    StateObject state = new StateObject();
                    state.workSocket = clientSocket;
                    clientSocket.BeginReceive(state.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(ReceiveCallback), state);
                    Console.WriteLine("BeginReceive 执行完毕");
                }
                catch (Exception ex)
                {

                }
            }
        }

        /// <summary>
        /// 接收消息回掉函数
        /// </summary>
        /// <param name="ar"></param>
        private static void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                StateObject so = (StateObject)ar.AsyncState;
                Socket s = so.workSocket;
                int read = s.EndReceive(ar);
                if (read > 0)
                {
                    string msg = Encoding.ASCII.GetString(so.buffer, 0, read);
                }
            }
            catch (Exception ex)
            {

            }
        }

        public class StateObject
        {
            public Socket workSocket = null;
            public const int BUFFER_SIZE = 1024;
            public byte[] buffer = new byte[BUFFER_SIZE];
            public StringBuilder sb = new StringBuilder();
        }
    }
}

问题补充:

此问题已经解决了,解决思路
1.同步发,同步接的Demo我也做了一份,发送没有问题,接收也没有问题
2.异步发,异步接的这个Demo,在异步接里面报错EndReceive报“远程主机强迫关闭了一个现有的连接问题”就有问题,所以我就想,那么我就用异步发,同步接总行了吧,果然同步接就好着呢,可以接到异步发来的消息
3.我就想同样的异步发代码,但是同步接可以接到消息,异步接就报错不行,我就对比同步接和异步接的代码,发现问题如下,果然问题出现在这里了,修复后,异步发异步接就好了
如下图所示
同步接代码




而异步接里面直接用的是clientSocket,没有用clientSocket.Accept()去得到一个新的Scoket


改造异步接代码如下图所示就好了


执行结果如下

David.Meng的主页 David.Meng | 初学一级 | 园豆:10
提问于:2016-04-12 22:49
< >
分享
最佳答案
0

 

没看明白。为什么 ServerSocket 不是 bind 、listen、accept?

奖励园豆:5
Launcher | 高人七级 |园豆:45050 | 2016-04-13 09:20

恩,是的,我拿异步接的代码对比了同步接的代码,确实发现有3个点是错误的,异步接代码写的有问题,里面没有使用到bind,listen,accept,恰恰就是需要这3个点

David.Meng | 园豆:10 (初学一级) | 2016-04-13 10:17
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册