首页 新闻 搜索 专区 学院

C#Socket客户端闪退

0
悬赏园豆:15 [已解决问题] 解决于 2015-01-23 09:02

这是我写的一个“socket异步通信”,具体代码如下,服务器是可以正常接收客户端发送的消息,

但是发了几条之后客户端就自己关闭了,各种trycatch也没抓到异常,求大神给看看

服务器代码:

 1     class Program
 2     {
 3         static Socket listener;
 4         static byte[] buffer = new byte[1024];
 5 
 6         static void Main(string[] args)
 7         {
 8             try
 9             {
10                 Start();
11             }
12             catch (SocketException ex)
13             {
14                 Console.WriteLine(ex.Message);
15             }
16            
17             Console.ReadKey(false);
18         }
19 
20         static void Start()
21         {
22             IPEndPoint point = new IPEndPoint(IPAddress.Any, 40001);
23             listener = new Socket(point.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
24             listener.Bind(point);
25             listener.Listen(10);
26             listener.BeginAccept(AcceptCallback, listener);
27         }
28 
29         private static void AcceptCallback(IAsyncResult ar)
30         {
31             Socket server = ar.AsyncState as Socket;
32             Socket accept = server.EndAccept(ar);
33             server.BeginAccept(AcceptCallback, listener);
34             accept.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, accept);
35 
36         }
37 
38         private static void ReceiveCallback(IAsyncResult ar)
39         {
40             Socket accept = ar.AsyncState as Socket;
41             try
42             {
43                 Int32 length = accept.EndReceive(ar);
44                 Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, length));
45                 accept.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, accept);
46             }
47             catch (SocketException ex)
48             {
49                 Console.WriteLine(ex.Message);
50             }
51             
52         }
53     }

客户端代码:

 1    class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             try
 6             {
 7                 Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 8                 client.BeginConnect(IPAddress.Parse("127.0.0.1"), 40001, RequestCallback, client);
 9 
10             }
11             catch (Exception ex)
12             {
13                 Console.WriteLine(ex.Message);
14             }
15             Console.ReadKey();
16 
17         }
18 
19         private static void RequestCallback(IAsyncResult ar)
20         {
21 
22             Socket client = ar.AsyncState as Socket;
23             try
24             {
25                 client.EndConnect(ar);
26                 while (true)
27                 {
28                     Console.WriteLine("请输入发送的内容:");
29                     string message = string.Format("{0}发送了:{1}", client.LocalEndPoint, Console.ReadLine());
30                     byte[] buffer = Encoding.UTF8.GetBytes(message);
31                     client.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, SendCallback, client);
32                 }
33             }
34             catch (Exception ex)
35             {
36                 Console.WriteLine(ex.Message);
37             }
38         }
39 
40         private static void SendCallback(IAsyncResult ar)
41         {
42             Socket client = ar.AsyncState as Socket;
43             try
44             {
45                 Int32 length = client.EndSend(ar);
46                 Console.WriteLine("消息长度:{0}", length);
47             }
48             catch (SocketException ex)
49             {
50                 Console.WriteLine(ex.Message);
51             }
52         }
53     }

还有有人(csdn上的一个帖子评论人)说msdn的socket异步通信并非真正的异步通信(通过ManualResetEvent线程事件实现),那什么是真正的异步通信?谁能给个地址去看下,或者给讲解下,我是真的百度谷歌很久没看明白所以才来问的,如果你不屑回答如此简单的问题也请高台贵手勿喷,小菜鸟心灵脆弱啊。

yangsofter的主页 yangsofter | 初学一级 | 园豆:199
提问于:2015-01-22 17:07
< >
分享
最佳答案
0

应该是 Console.ReadLine() 的问题,程序正确退出了。

是真正的异步,底层使用  WSA_FLAG_OVERLAPPED 创建 SOCKET 句柄。IAsyncResult 通过 LazyAsyncResult 实现,调用 EndXXX 或 WaitHandle 时并不总是会创建 ManualResetEvent 对象。

 

在 main 中 Console.ReadKey 同 Console.ReadLine() 冲突。

收获园豆:5
Launcher | 高人七级 |园豆:45045 | 2015-01-22 17:30

感谢大家的回复,看了Launcher的回复,突然发现我忽略了一个问题,我忘记了异步连接(client.BeginConnect(...))的时候代码还是会往下执行(即使RequestCallback方法中还有个while (true)),所以他退出的时候应该是执行到了Console.ReadKey(),我就说我写着写着他就自己退出了。是这个原因吧?

yangsofter | 园豆:199 (初学一级) | 2015-01-23 09:02
其他回答(2)
0

我们是这样实现socket异步的,详见博文:走进异步世界:EnyimMemcached异步化改造引起的内存泄漏

收获园豆:5
dudu | 园豆:37242 (高人七级) | 2015-01-22 17:28

把代码下下来了,留到以后学习了,现在还看不懂,哈哈

支持(0) 反对(0) yangsofter | 园豆:199 (初学一级) | 2015-01-23 09:06
0

你的是异步通信,只要是BeginXXXXX这样子的 类 都是另开一个线程

收获园豆:5
田麦成 | 园豆:2004 (老鸟四级) | 2015-01-22 17:30
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册