通讯学习-循序渐进2

通信学习-----循序渐进22.多线程服务器的实现??在前面已经实现的服务器是不能让多个客户端连接进来的,只能

通信学习-----循序渐进2

2.多线程服务器的实现

?

?

在前面已经实现的服务器是不能让多个客户端连接进来的,只能让单个客户端的接入,首先阐明一点不能够让多个客户端接入的原因:ServerSocket在调用accept方法时是阻塞的,在一个客户端接入后,另外需要连接进来的客户端必须等待前面这个客户端正常退出以后才能够进入。有了多线程的知识,我们就可以让阻塞的部分在一个独立的线程里面独立的运行,每当一个客户端接入以后就创建一个线程对象去处理,这就是多线程服务器的基本原理。下面看代码示例:

?

?

首先创建ServerSocket对象,打开一个端口,让客户端连接进来这个类主要负责构建服务器

import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class ServerSet{private InputStream in;private OutputStream ou;private ServerSocket ss;/** * 创建服务器 *  * @param port *            :端口号 */public void setupServer(int port) {try {// 创建服务器套接字ss = new ServerSocket(port);while(true){Socket sc=ss.accept();//创建客户端处理线程对象ServerThread st=new ServerThread(sc);//启动线程st.start();}} catch (Exception ef) {ef.printStackTrace();}}//程序入口public static void main(String args[]) {ServerSet s=new ServerSet();s.setupServer(12345);}}

?

?

单独创建一个线程类,处理客户端的阻塞部分

import java.io.InputStream;   import java.io.OutputStream;   import java.net.Socket;     public class ServerThread extends Thread{       private Socket sc;       private InputStream in;       private OutputStream ou;                     /**       * 通过该类的构造器方法把需要的参数传递过来       * @param sc:客户端套接字对象       */      public ServerThread(Socket sc){           this.sc=sc;       }                            public void run(){           this.clientPro();       }              /**       * 处理客户端的方法       */      public void clientPro(){           try{                              System.out.println("一个客户端接入");               //得到输入输出流对象               in=sc.getInputStream();               ou=sc.getOutputStream();                              String s="欢迎那个谁!";               this.sendMsg(s);                              int t;               //遇到回车结束读取               while((t=in.read())!=13){                                      System.out.println(t);               }                              //关闭客户端的链接               sc.close();           }catch(Exception ef){               ef.printStackTrace();           }                  }                            //发送信息的私有方法       private void sendMsg(String msg)throws Exception{           ou.write(msg.getBytes());           ou.flush();       }                        }  

?

?

?