Socket(二)尝试多线程的服务端

   上次的服务端一次只能跟一个客户端连接。下午决定结合前面学习的线程的知识,更改一下,改成多线程的服务端。

  这里只是简单的尝试。等我学的知识增加了,会写出更好的来的。

  服务端代码:

 

Code:
  1. package Socket;  
  2. /**  
  3.  * @author Geek_Soledad  
  4.  * @creation date 2011-4-24 上午08:22:39  
  5.  *  
  6.  */  
  7. import java.io.*;  
  8. import java.net.*;  
  9.   
  10. public class TCPServer implements Runnable{  
  11.     ServerSocket ss;  
  12.     Socket s;  
  13.     public static void main( String[] args) {  
  14.         TCPServer tcpServer = new TCPServer();  
  15.         try {  
  16.             tcpServer.ss = new ServerSocket(10086); // Server start  
  17.             while (true) {  
  18.                 tcpServer.s = tcpServer.ss.accept(); // waiting for connection  
  19.                 new Thread(tcpServer).start();  
  20.             }  
  21.         } catch (IOException e) {  
  22.             // TODO Auto-generated catch block  
  23.             e.printStackTrace();  
  24.         }  
  25.     }  
  26.     @Override  
  27.     public void run() {  
  28.         // TODO Auto-generated method stub  
  29.         message();  
  30.     }  
  31.     void message() {  
  32.         String name;  
  33.         DataInputStream dis;  
  34.   
  35.         try {  
  36.             dis = new DataInputStream(s.getInputStream());  
  37.             name = dis.readUTF();  
  38.             System.out.println(name + "已连接!");  
  39.               
  40.             String is = dis.readUTF();  
  41.               
  42.             while("exit".equalsIgnoreCase(is) == false) {  
  43.                 System.out.println(name+":"+is);  
  44.                 is = dis.readUTF();  
  45.             }  
  46.               
  47.             dis.close();  
  48.             s.close();  
  49.             System.out.println(name + "已退出");  
  50.         } catch (IOException e) {  
  51.             // TODO Auto-generated catch block  
  52.             e.printStackTrace();  
  53.         }  
  54.     }  
  55. }  

 

  运行客户端时,第一个参数指定了客户端的名字。代码如下:

Code:
  1. package Socket;  
  2. /**  
  3.  * @author Geek_Soledad  
  4.  * @creation date 2011-4-24 上午08:30:47  
  5.  *  
  6.  */  
  7. import java.io.*;  
  8. import java.net.*;  
  9.   
  10. public class TCPClient {  
  11.     String name = "noname";  
  12.     public static void main( String[] args) {  
  13.         TCPClient client = new TCPClient();  
  14.         if (args.length>0) {  
  15.             client.name = args[0];  
  16.         }  
  17.         client.connection();  
  18.   
  19.     }  
  20.       
  21.     void connection(){  
  22.         try {  
  23.             Socket s = new Socket("127.0.0.1"10086);  
  24.             System.out.println("成功连上服务端");  
  25.             DataOutputStream dos = new DataOutputStream(  
  26.                     s.getOutputStream());  
  27.             BufferedReader bf = new BufferedReader(  
  28.                     new InputStreamReader(System.in));  
  29.             String words ;  
  30.               
  31.             // 发送出客户端名字  
  32.   
  33.             dos.writeUTF(name);  
  34.   
  35.             // 开始通信  
  36.             do {  
  37.                 words = bf.readLine();  
  38.                 dos.writeUTF(words);  
  39.             } while("exit".equalsIgnoreCase(words) == false);  
  40.               
  41.             s.close();  
  42.         } catch (UnknownHostException e) {  
  43.             // TODO Auto-generated catch block  
  44.             e.printStackTrace();  
  45.             System.out.println("服务器IP错误");  
  46.         } catch (IOException e) {  
  47.             // TODO Auto-generated catch block  
  48.             e.printStackTrace();  
  49.             System.out.println("无法连接主机");  
  50.         }  
  51.     }  
  52. }  

  刚才发客户端的代码时,又对它改了一下,把连接部分放到函数connection中。

 

  刚才又尝试了一下,在其中一个客户端退出时有时会出现s.close()被调用,导致另一个客户端断开,不知是什么原因。可能我对多线程还得再学习学习。

上一篇:对象布局已知时 C++ 对象指针的转换时地址调整


下一篇:第三篇 :微信公众平台开发实战Java版之请求消息,响应消息以及事件消息类的封装