天道酬勤

博观而约取,厚积而薄发!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

我的IM - 基础篇[1] - Socket 【转载】

Posted on 2010-04-29 16:25  Happy Coding  阅读(555)  评论(0编辑  收藏  举报

看到那么多人支持,我很感动,所以临时决定从今天开始讲述如何编写IM。

那么今天开始第一讲, Socket.

  

  为什么上来就讲Socket呢?因为我觉得作为一个对于IM很感兴趣的人,应该瞬间提升对于网络编程的高度认知,只有这样才能快速的学到东西。

那么好了,开始实战!

  Socket又分为异步套接字和同步套接字,我在项目中基本上都是用的同步(当然,您可以使用异步),然后自己New的线程,这样的话,我感觉有几点好处。

  1. 对于线程拥有更加的认知度。

  2. 启用了自己制作的线程池(ThreadPool <-这个我自己写了个)

  

  那么先说线程,Socket监听一般是需要2个While--true的,这个也是通用写法,貌似很多学校也这样教?

  那么下面进入代码时间,我先来粘贴出一段有问题的代码(服务端部分):

 

       

Code
 
 

  上面这段代码减去了没必要的部分,但是足足可以说明问题,上面这段代码运行是没有问题的,而且能监听指定端口。

不知道您看出问题了吗?

  慢慢的,你就会发现,这段代码有问题了,而且有大问题,因为当我有1个用户上线并且成功与服务器连接后,再来一个用户上线,那么第一个

用户便不会再与服务器进行任何响应了,这是为什么呢?

  呵呵 ,可能有人看出来了?服务器第一个While循环为了得到用户的SOCKET,当得到后,传递到第二个While,这样一来,就会一直在第二个While循环中

出不来了……而且整个窗体会卡住。

  么好,我们改下,比如现在把第二个While用多线程处理,看代码(服务端部分):

 

 

Code
                            }
                        }
                        
else
                        {
                            
//do sth                      
          }                        
                    }
                    
else
                    {
                        
//MessageBox.Show("套接字已经断开了");
                    }
                }

            }
        }
 
呵 太多了,我就不精简了,总体来说,这次是用了多线程,将第二个While包在了方法体内,
然后第二个While监听全局的Socket。
那么这样一来,是不是比刚才好了呢???
是我告诉你,这段代码还是有问题,而且是一个大问题,你看出来了吗?
 
那么,这段代码运行后,出现的问题是,虽然窗体不卡了,但是,当第二个用户登录到服务器后,第一个用户同样还是
无法与服务器产生任何响应了!!
 
这是为什么呢??
 
  让我们来仔细研究代码,当地一个用户连接服务器的时候,服务器得到了第一个用户的Socket且把它赋值到全局
然后第二个While就会循环监听这个全局的Socket,那么,当第二个用户连接服务器的时候,还是按照规矩,将第二个用户的Socket
赋值全局,这样问题就来了!!第一个用户的Socket不是就被覆盖了吗?是的!!这个就是问题所在。
 
  那么我现在给出本次讲解中,真正正确的解决方案,同时这个方案也被包含在了我自己的通讯框架中。
我们需要2个类。第一个类负责监听端口,(当然了还是While,但是要运行在多线程中,否则会卡屏哦),当接受了用户连接后,
得到用户连接,开始实例化第二个类,我管第二个类叫做"MessageListener",第一个类叫做"PortListener",那么我的第二个类构造是这样写的(简单版本)
Code
这样一来,实例化的时候,传递当前得到的用户SOCKET,然后调用MessageListener的Start()方法就可以了。
MessageListener的Start()方法(简单版本)无非就是这样:
Code
调用了内部的私有方法private void INNER_LISTENER()来进行While循环。
 
 
以上是简单版本的解决方案。下面提供了我的UML框架部分截图 (我的框架支持UDP和TCP 2种)
大家先看下,作为了解:
 
 
 
好了,截图了我的UML框架作为结尾,是再好不过了,新手作为了解,老鸟作为补习。
 
如果有错的地方 请勿见怪(以上代码实例,来自我的N年前接触网络时的处女作品)。