分享

Java实现简单的Socket服务器与客户端字符串通讯(适合初学者阅读)

 hehffyy 2011-11-25

服务器端代码:

 

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. import java.io.BufferedReader;  
  2. import java.io.IOException;  
  3. import java.io.InputStreamReader;  
  4. import java.io.PrintStream;  
  5. import java.net.ServerSocket;  
  6. import java.net.Socket;  
  7. /** 
  8.  * Socket通讯服务器端 
  9.  * @author 米强<如转载请保留作者和出处> 
  10.  * @blog http://hi.baidu.com/mq612/blog 
  11.  * @blog http://blog.csdn.net/mq612 
  12.  */  
  13. public class ServerMain {  
  14.     public ServerMain() {  
  15.         try {  
  16.             // 构造服务器ServerSocket对象,参数为服务器端开放的端口号  
  17.             ServerSocket ss = new ServerSocket(30102);  
  18.             System.out.println("服务器准备就绪!");  
  19.             // 死循环可以使服务器持续处于接收客户端状态  
  20.             while(true){  
  21.                 // 该方法使程序阻塞,等待客户端的链接,当监听到客户端的链接,创建一个Socket对象与客户端单独会话  
  22.                 Socket s = ss.accept();  
  23.                 // 为了不影响服务器监听其它客户端,这里开启了一个线程,由线程处理与这个客户端的会话  
  24.                 new ServerThread(s).start();  
  25.             }  
  26.         } catch (IOException e) {  
  27.             e.printStackTrace();  
  28.         }  
  29.     }  
  30.     public static void main(String[] args) {  
  31.         new ServerMain();  
  32.     }  
  33. }  
  34.   
  35. /** 
  36.  * 服务器端与客户端会话的线程 
  37.  */  
  38. class ServerThread extends Thread {  
  39.     private Socket s = null;  
  40.     private BufferedReader read = null;  
  41.     private PrintStream print = null;  
  42.     public ServerThread(Socket s) {  
  43.         this.s = s;  
  44.         try {  
  45.             // 从Socket中获取输入流和输出流,由于我们只做一个简单的字符串通讯,所以采用BufferedRead和PrintStream来封装输入、输出流  
  46.             read = new BufferedReader(new InputStreamReader(s.getInputStream()));  
  47.             print = new PrintStream(s.getOutputStream());  
  48.         } catch (IOException e) {  
  49.             e.printStackTrace();  
  50.         }  
  51.     }  
  52.     /** 
  53.      * 线程的运行run方法 
  54.      */  
  55.     public void run() {  
  56.         try {  
  57.             String message = null;  
  58.             // 这里循环可以使服务器持续的接收客户端信息。read.readLine()通过输入流读取一段字符串,赋值给message变量,如果message字符串不为“exit”则循环,否则结束循环  
  59.             while (!(message = read.readLine()).equals("exit")){  
  60.                 // 将字符串前面添加“返回:”,再发回客户端  
  61.                 print.println("返回:" + message);  
  62.             }  
  63.         } catch (IOException e) {  
  64.         } finally {  
  65.             // 在 finally 代码块中无论如何都会执行下面代码:  
  66.             try {  
  67.                 // 如果没有关闭Socket  
  68.                 if(!s.isClosed()){  
  69.                     // 关闭Socket链接  
  70.                     s.close();  
  71.                 }  
  72.             } catch (IOException e1) {  
  73.                 e1.printStackTrace();  
  74.             }  
  75.         }  
  76.     }  
  77. }  

 

客户端代码:

 

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. import java.io.BufferedReader;  
  2. import java.io.IOException;  
  3. import java.io.InputStreamReader;  
  4. import java.io.PrintStream;  
  5. import java.net.Socket;  
  6. import java.net.UnknownHostException;  
  7. import java.util.Scanner;  
  8. /** 
  9.  * Socket通讯客户端 
  10.  * @author 米强<如转载请保留作者和出处> 
  11.  * @blog http://hi.baidu.com/mq612/blog 
  12.  * @blog http://blog.csdn.net/mq612 
  13.  */  
  14. public class ClientMain {  
  15.     public ClientMain() {  
  16.         try {  
  17.             // 构造与服务器通讯的Socket对象,参数为服务器IP地址(String)和端口号(int),端口号需要和服务器端开放的端口号对应  
  18.             Socket s = new Socket("192.168.1.100"30102);  
  19.             // 启动一个线程与服务器通讯,并把链接服务器的Socket对象传递过去  
  20.             new LinkThread(s).start();  
  21.         } catch (UnknownHostException e) {  
  22.             e.printStackTrace();  
  23.         } catch (IOException e) {  
  24.             e.printStackTrace();  
  25.         }  
  26.     }  
  27.       
  28.       
  29.     public static void main(String[] args) {  
  30.         new ClientMain();  
  31.     }  
  32.       
  33. }  
  34. /** 
  35.  * 与服务器通讯的线程 
  36.  */  
  37. class LinkThread extends Thread {  
  38.     private Socket s = null;  
  39.     // 输出流  
  40.     private PrintStream out = null;  
  41.     // 缓冲输入流  
  42.     private BufferedReader in = null;  
  43.     // 录入文字的Scanner对象  
  44.     private Scanner scanner = null;  
  45.       
  46.     public LinkThread(Socket s) {  
  47.         // 将Socket对象实例保存在全局变量中,因为run方法中我们还要用它断开链接  
  48.         this.s = s;  
  49.         try {  
  50.             // 从Socket中获取输入流和输出流,由于我们只做一个简单的字符串通讯,所以采用BufferedRead和PrintStream来封装输入、输出流  
  51.             out = new PrintStream(s.getOutputStream());  
  52.             in = new BufferedReader(new InputStreamReader(s.getInputStream()));  
  53.         } catch (UnknownHostException e) {  
  54.             e.printStackTrace();  
  55.         } catch (IOException e) {  
  56.             e.printStackTrace();  
  57.         }  
  58.     }  
  59.       
  60.     /** 
  61.      * 线程的运行run方法 
  62.      */  
  63.     public void run() {  
  64.         // 构造Scanner对象  
  65.         scanner = new Scanner(System.in);  
  66.         System.out.println("提示:如果要结束本次会话,请输入“exit”指令!");  
  67.         try {  
  68.             // 死循环可以使客户端不断的向服务器发送信息,不用担心循环无法结束,后面的return语句可以结束整个线程。  
  69.             while(true){  
  70.                 // 提示用户输入文字  
  71.                 System.out.print("请输入:");  
  72.                 // 将用户输入的字符串保存在message变量中  
  73.                 String message = scanner.nextLine();  
  74.                 // 通过输出流发送字符串  
  75.                 out.println(message);  
  76.                 // 清空缓冲,强制输出  
  77.                 out.flush();  
  78.                 // 获取服务器返回的字符串  
  79.                 String str = in.readLine();  
  80.                 // 如果返回的字符串存在  
  81.                 if(str != null){  
  82.                     // 显示在控制台  
  83.                     System.out.println(str);  
  84.                 }else{  
  85.                     // 提示会话结束,并结束线程  
  86.                     System.out.println("本次会话结束!");  
  87.                     return;  
  88.                 }  
  89.             }  
  90.         } catch (IOException e) {  
  91.             e.printStackTrace();  
  92.         } finally {  
  93.             // 在 finally 代码块中无论如何都会执行下面代码:  
  94.             try {  
  95.                 // 如果没有关闭Socket  
  96.                 if(!s.isClosed()){  
  97.                     // 关闭Socket链接  
  98.                     s.close();  
  99.                 }  
  100.             } catch (IOException e1) {  
  101.                 e1.printStackTrace();  
  102.             }  
  103.         }  
  104.     }  
  105.       
  106. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多