java Socket通信实例

http://blog.csdn.net/zhqingyun163/article/details/7991389

一直做Java web,几乎没有做过CS方向上的东西。最近一同学来北京找工作,到我这儿来玩。说起笔试经历,说了这样一个程序题,大概是这样的;

   用C++编程实现一个简单的通信实例,要求服务器实时接受客户端发送来的消息。虽说没做过这方面的东西,但也知道需要用Java Socket来实现(坦白说C++不会)。工作之余花了2个小时写了一个基本满足要求的实例。也确实遇到了一些问题,贴出来,共同学习。

先贴代码。服务器端:

[java]  view plain copy
  1. package qy.server;  
  2.   
  3. import java.io.DataInputStream;  
  4. import java.io.DataOutputStream;  
  5. import java.io.IOException;  
  6. import java.net.ServerSocket;  
  7. import java.net.Socket;  
  8. import java.util.concurrent.ExecutorService;  
  9. import java.util.concurrent.Executors;  
  10.   
  11. public class MyServer {  
  12.     private ServerSocket serverSocket; //   
  13.     private ExecutorService servicePool; // 线程池  
  14.   
  15.     public MyServer(int port) {  
  16.         try {  
  17.             this.serverSocket = new ServerSocket(port);  
  18.             this.servicePool = Executors.newFixedThreadPool(5);  
  19.         } catch (IOException e) {  
  20.             e.printStackTrace();  
  21.         }  
  22.     }  
  23.   
  24.     public static void main(String[] args) {  
  25.         new MyServer(6666).service();   
  26.     }  
  27.   
  28.     public void service() {  
  29.         int i = 0;  
  30.         while (true) {  
  31.             try {  
  32.                 Socket socket = this.serverSocket.accept(); // 接受到一个连接,并且返回一个客户端的Socket对象实例  
  33.                 this.servicePool.execute(new Handler(socket));  
  34.                 System.out  
  35.                         .println("User " + i + " is connecting to the Server");  
  36.                 i++;  
  37.             } catch (IOException e) {  
  38.                 e.printStackTrace();  
  39.                 this.servicePool.shutdown();  
  40.             }  
  41.         }  
  42.     }  
  43.   
  44.     class Handler implements Runnable {  
  45.         private Socket socket;  
  46.   
  47.         public Handler(Socket socket) {  
  48.             this.socket = socket;  
  49.         }  
  50.   
  51.         @Override  
  52.         public void run() {  
  53.             try {  
  54.                 // 一个输入流,用于获取客户端传来的内容  
  55.                 DataInputStream dis = new DataInputStream(  
  56.                         this.socket.getInputStream());  
  57.                 // 用于产生服务器准备响应的内容  
  58.                 DataOutputStream dos = new DataOutputStream(this.socket.getOutputStream());  
  59.                 String str;  
  60.                 while (null != (str = dis.readUTF())) {  
  61.                     System.out.println(str);  
  62.                     if ("exit".equals(str)) {  
  63.                         System.out.println("客户端发出中断请求");  
  64.                         dos.writeUTF("服务器已经关闭本次连接.");  
  65.                         dos.flush();  
  66. //                      dos.writeUTF("exit"); //   
  67. //                      dos.flush();  
  68.                           
  69.                         dos.close();  
  70.                         dis.close();  
  71.                         break;  
  72.                     }  
  73.                 }  
  74.   
  75.             } catch (IOException e) {  
  76.                 e.printStackTrace();  
  77.             }  
  78.         }  
  79.     }  
  80. }  
然后,客户端:

[java]  view plain copy
  1. package qy.client;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.DataInputStream;  
  5. import java.io.DataOutputStream;  
  6. import java.io.IOException;  
  7. import java.io.InputStreamReader;  
  8. import java.net.Socket;  
  9.   
  10. public class MyClient {  
  11.   
  12.     public static void main(String[] args) {  
  13.         try {  
  14.             Socket client = new Socket("localhost"6666);  
  15.             MyClient me = new MyClient();  
  16.             new Thread(me.new Handler(client)).start();  
  17.         } catch (IOException e) {  
  18.             e.printStackTrace();  
  19.         }  
  20.     }  
  21.   
  22.     class Handler implements Runnable {  
  23.         private BufferedReader br;  
  24.         private DataOutputStream dos;  
  25.         private DataInputStream dis;  
  26.         private Socket socket;  
  27.         private boolean flag = true// 用于控制循环结束  
  28.   
  29.         public Handler(Socket s) throws IOException {  
  30.             this.br = new BufferedReader(new InputStreamReader(System.in)); // 用于从控制台接受输入的信息,再发送到服务器  
  31.             this.socket = s;  
  32.             this.dos = new DataOutputStream(this.socket.getOutputStream()); // 向服务器写数据的输出流  
  33.             this.dis = new DataInputStream(this.socket.getInputStream()); // 获取服务器返回数据的输入流  
  34.         }  
  35.   
  36.         @Override  
  37.         public void run() {  
  38.             while (flag) {  
  39.                 try {  
  40.                     String str = br.readLine();  
  41.                     if ("exit".equals(str)) { // 客户端终止发送信息标记 exit  
  42.                         this.br.close();   
  43.                         this.dos.writeUTF(str);  
  44.                         this.dos.flush();  
  45.                           
  46.                         String res = dis.readUTF();  
  47.                         System.out.println(res);  
  48.   
  49.                         this.dis.close();  
  50.                         this.dos.close();  
  51.                         this.flag = false;  
  52.                     } else {  
  53.                         this.dos.writeUTF(str);// 每读一行就发送一行  
  54.                         this.dos.flush();  
  55.                     }  
  56.   
  57.                 } catch (IOException e) {  
  58.                     e.printStackTrace();  
  59.                 }  
  60.             }  
  61.         }  
  62.     }  
  63. }  

遇到的问题:

最先考虑的是使用BufferedReader和BufferedWriter来完成双向数据的写入写出,但是发现BufferedWriter在fush()的时候并不能把从控制台得到的数据立即发送到服务端,就改用DataOutputStream数据流来完成双向数据传递。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值