代码改变世界

服务器的搭建

2016-10-19 16:58  Jason林  阅读(188)  评论(0编辑  收藏  举报

服务器的搭建

1、创建一个ServerSocket对象。

ServerSocket Server=new ServerSocket(7777); //端口为7777

2、服务器无限期地监听。
Socket s=Server.accept();
3、获取 OutputStream 和 InputStream 对象,使服务器能够通过发送和接收字节与客户进行通信。服务器调用 Socket 的方法,getOutputStream 获取对 Socket 的 OutputStream 的引用,调用 Socket  的方法 getInputStream 获取对 Socket 的 InputStream 的引用。

OutputStream out=s.getOutputStream();
DataOutputStream dos=new DataOutputStream(out);
InputStream in=s.getInputStream();
DataInputStream dis=new DataInputStream(in);

4、处理阶段,客户和服务器通过 DataOutputStream 和 DataInputStream 对象进行通信。
5、当传输完成时,需要关闭连接以及IO流。

dis.close();
dos.close();
s.close();

以上的服务器搭建方式仅仅允许一个客户端的连接,若要允许多个客户端的接入,则需要多线程来处理。

1、用一个循环无限期监听客户端的连接,每当连接上一个客户端,则向ConnectedClient类型的集合中加入一个线程,同时将这个客户端的socket传到该线程中。

ArrayList<ConnectedClient> clients=new ArrayList<ConnectedClient>();
while
(true){ s = ss.accept(); System.out.println("客户端已连接"); ConnectedClient cc = new ConnectedClient(s); new Thread(cc).start(); clients.add(cc);
}
private class ConnectedClient implements Runnable {
  Socket s = null;
  public ConnectedClient(Socket s) {
            this.s = s;
  }
}

2、在该线程的run()方法中对数据的读取输出进行操作。先接收其中一个客户端发来的消息,再通过for循环将这个消息通过sendMessage(str)方法发送给所有的客户端。

public void sendMessage(String str){
            try {
                dos.writeUTF(str);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

 

    public void run() {
       try{
       
while(true){    String string=dis.readUTF();    for(int i=0;i<clients.size();i++){    ConnectedClient cc=clients.get(i);    cc.sendMessage(string);    }    } }catch(IOException e){
      e.printStackTrace();
    } }

这样允许多个客户端连接并同时通信的多线程服务器就搭建完成。完整代码如下(其中增加了对Exception的处理,这部分以后再写):

public class Server {

    private ServerSocket ss;
    private Socket s;
    private boolean started=false;
    private ArrayList<ConnectedClient> clients=new ArrayList<ConnectedClient>();
    public static void main(String[] args) {
        Server server = new Server();
        server.creatServer(7777);
    }

    public void creatServer(int port) {
        try {
            ss = new ServerSocket(port);
            started=true;
        }catch(BindException e){
            JOptionPane.showMessageDialog(null, "端口使用中,请关闭相关程序并重新启动!");
            System.exit(0);
        }catch (IOException e) {
            e.printStackTrace();
        }
        try{
            while(started){
                s = ss.accept();
                System.out.println("客户端已连接");
                ConnectedClient cc = new ConnectedClient(s);
                new Thread(cc).start();
                clients.add(cc);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(ss!=null) ss.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    private class ConnectedClient implements Runnable {

        String str=null;
        Socket s = null;
        OutputStream out=null;
        InputStream in=null;
        DataOutputStream dos=null;
        DataInputStream dis=null;

        public ConnectedClient(Socket s) {
            this.s = s;
            try{
                out=s.getOutputStream();
                in=s.getInputStream();
                dos=new DataOutputStream(out);
                dis=new DataInputStream(in);
                dos.writeUTF("欢迎连接服务器");
            }catch(IOException e) {
                e.printStackTrace();
            }
        }
        
        public void sendMessage(String str){
            try {
                dos.writeUTF(str);
            } catch (IOException e) {
                clients.remove(this);
                System.out.println("一个客户端已经退出了");
                //e.printStackTrace();
            }
        }
        
        public void run() {
            
            try{    
                while(true){    
                    String string=dis.readUTF();
                    for(int i=0;i<clients.size();i++){
                        ConnectedClient cc=clients.get(i);
                        cc.sendMessage(string);
                    }
                }
            }catch(EOFException e){
                System.out.println("一个客户端退出了!");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (dis != null)
                        dis.close();
                    if (s != null)
                        s.close();
                    if (dos != null)
                        dos.close();
                } catch (IOException e) {

                    e.printStackTrace();
                }

            }
            
        }

    }
}