网络编程之Socket通信(Java)进阶版

之前在前面已经介绍了Socket通信的一些基本原理,以及如何让客户端与服务器端建立通信,和实现通信的一些基本步骤(包括首先使得服务器端与客户端建立连接,建立连接之后,服务器端开始侦听客户端的请求,侦听到客户端的请求之后,通过输入输出流处理相关信息实现通信,最后通信完毕结束通信等一系列流程)。

但是之前只是单个客户端与服务器进行通信,而我们实际应用中单个客户端的情况几乎不存在,都是多个客户端同时与服务器进行交互(这里同时交互就会出现并发性的问题,对于并发性的问题暂时还不是很懂,只知道有这个概念),那就需要服务器端不停的侦听客户端的请求(写在while循环中,并且条件始终为true,死循环),每当侦听到一个客户端的请求时,都需要创建一个Socket与之建立通信(通过线程实现,每当侦听到一个客户端的请求,服务端都要单独开辟一条线程与之进行通信)。


下面直接贴代码吧:


1、服务端Socket,(这里面通过死循环让服务器端一直循环侦听来自客户端的请求)

需要注意的是,服务端必须要先于客户端启动,因为要启动之后才能侦听客户端的请求


  1. package com.socket;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.ServerSocket;  
  5. import java.net.Socket;  
  6.   
  7. /** 
  8.  * 服务器端Socket 
  9.  * @author feizi 
  10.  * @time 2014-11-14下午5:08:16 
  11.  */  
  12. public class ServerSocketMany {  
  13.       
  14.     /** 
  15.      * main测试方法 
  16.      * @param args 
  17.      * @throws IOException 
  18.      */  
  19.     public static void main(String[] args) throws IOException{  
  20.           
  21.         System.out.println("服务器已经启动,等待客户端的连接....");  
  22.           
  23.         //创建服务器端Socket,即ServerSOcket,等待客户端的请求  
  24.         ServerSocket server = new ServerSocket(5555);  
  25.           
  26.         int count = 0;//侦听到的客户端的数量  
  27.           
  28.         Socket socket = null;//服务器端Socket  
  29.           
  30.         //死循环,让服务端循环侦听  
  31.         while(true){  
  32.               
  33.             //服务端开始侦听客户端的连接  
  34.             socket = server.accept();  
  35.               
  36.             //启动线程,与客户端进行通信  
  37.             Thread serverThread = new ServerThread(socket);  
  38.             serverThread.start();  
  39.               
  40.             //计数,统计客户端连接数  
  41.             count++;  
  42.               
  43.             System.out.println("当前链接的客户端的数量为:"+count+"个....");  
  44.         }  
  45.     }  
  46. }  
package com.socket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务器端Socket
 * @author feizi
 * @time 2014-11-14下午5:08:16
 */
public class ServerSocketMany {
	
	/**
	 * main测试方法
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException{
		
		System.out.println("服务器已经启动,等待客户端的连接....");
		
		//创建服务器端Socket,即ServerSOcket,等待客户端的请求
		ServerSocket server = new ServerSocket(5555);
		
		int count = 0;//侦听到的客户端的数量
		
		Socket socket = null;//服务器端Socket
		
		//死循环,让服务端循环侦听
		while(true){
			
			//服务端开始侦听客户端的连接
			socket = server.accept();
			
			//启动线程,与客户端进行通信
			Thread serverThread = new ServerThread(socket);
			serverThread.start();
			
			//计数,统计客户端连接数
			count++;
			
			System.out.println("当前链接的客户端的数量为:"+count+"个....");
		}
	}
}


2、服务器端的线程实现类,线程中主要是实现与客户端的通信(通过输入输出流接收并响应数据信息)


  1. package com.socket;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.io.OutputStream;  
  8. import java.io.PrintWriter;  
  9. import java.net.Socket;  
  10.   
  11. /** 
  12.  * 创建一个服务端线程,循环侦听客户端的请求,多个客户端 
  13.  * @author feizi 
  14.  * @time 2014-11-14下午5:36:45 
  15.  */  
  16. public class ServerThread extends Thread{  
  17.   
  18.     //每当侦听到一个新的客户端的时,服务端这边都要有一个Socket与之进行通信  
  19.     public Socket socket = null;  
  20.       
  21.     //默认的构造方法,保留  
  22.     public ServerThread(){}  
  23.       
  24.     //带参构造方法  
  25.     public ServerThread(Socket socket){  
  26.         this.socket = socket;  
  27.     }  
  28.       
  29.     //覆写run方法  
  30.     public void run(){  
  31.         //获取输入字节流  
  32.         InputStream in = null;  
  33.           
  34.         //将输入字节流包装成输入字符流  
  35.         InputStreamReader isr = null;  
  36.           
  37.         //为字符输入流添加缓冲  
  38.         BufferedReader br = null;  
  39.           
  40.         //收到信息之后,向客户端响应信息,获取输出字节流  
  41.         OutputStream out = null;  
  42.           
  43.         //将字节输出流包装成字符打印输出流  
  44.         PrintWriter pw = null;  
  45.           
  46.         try {  
  47.               
  48.             in = socket.getInputStream();  
  49.             isr = new InputStreamReader(in);  
  50.             br = new BufferedReader(isr);  
  51.               
  52.             //读取字符输入流中的数据  
  53.             String data = null;  
  54.             while((data = br.readLine()) != null){  
  55.                 System.out.println("我是服务器,客户端说:"+data);  
  56.             }  
  57.               
  58.             //调用shutDown方法关闭Socket输入流  
  59.             socket.shutdownInput();  
  60.               
  61.             out = socket.getOutputStream();  
  62.             pw = new PrintWriter(out);  
  63.             pw.write("用户名和密码正确");  
  64.             pw.flush();  
  65.               
  66.             //调用shutDown方法关闭Socket输出流  
  67.             socket.shutdownOutput();  
  68.               
  69.         } catch (IOException e) {  
  70.             e.printStackTrace();  
  71.         }finally{  
  72.               
  73.             //关闭资源  
  74.             try {  
  75.                 if(null != pw)  
  76.                     pw.close();  
  77.                 if(null != out)  
  78.                     out.close();  
  79.                 if(null != br)  
  80.                     br.close();  
  81.                 if(null != isr)  
  82.                     isr.close();  
  83.                 if(null != in)  
  84.                     in.close();  
  85.                 if(null != socket)  
  86.                     socket.close();  
  87.             } catch (IOException e) {  
  88.                 e.printStackTrace();  
  89.             }  
  90.         }  
  91.     }  
  92. }  
package com.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * 创建一个服务端线程,循环侦听客户端的请求,多个客户端
 * @author feizi
 * @time 2014-11-14下午5:36:45
 */
public class ServerThread extends Thread{

	//每当侦听到一个新的客户端的时,服务端这边都要有一个Socket与之进行通信
	public Socket socket = null;
	
	//默认的构造方法,保留
	public ServerThread(){}
	
	//带参构造方法
	public ServerThread(Socket socket){
		this.socket = socket;
	}
	
	//覆写run方法
	public void run(){
		//获取输入字节流
		InputStream in = null;
		
		//将输入字节流包装成输入字符流
		InputStreamReader isr = null;
		
		//为字符输入流添加缓冲
		BufferedReader br = null;
		
		//收到信息之后,向客户端响应信息,获取输出字节流
		OutputStream out = null;
		
		//将字节输出流包装成字符打印输出流
		PrintWriter pw = null;
		
		try {
			
			in = socket.getInputStream();
			isr = new InputStreamReader(in);
			br = new BufferedReader(isr);
			
			//读取字符输入流中的数据
			String data = null;
			while((data = br.readLine()) != null){
				System.out.println("我是服务器,客户端说:"+data);
			}
			
			//调用shutDown方法关闭Socket输入流
			socket.shutdownInput();
			
			out = socket.getOutputStream();
			pw = new PrintWriter(out);
			pw.write("用户名和密码正确");
			pw.flush();
			
			//调用shutDown方法关闭Socket输出流
			socket.shutdownOutput();
			
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			
			//关闭资源
			try {
				if(null != pw)
					pw.close();
				if(null != out)
					out.close();
				if(null != br)
					br.close();
				if(null != isr)
					isr.close();
				if(null != in)
					in.close();
				if(null != socket)
					socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}



3、客户端Socket,这个和单客户端的情况一样,在第一篇中有详细介绍


  1. package com.socket;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.io.OutputStream;  
  8. import java.io.PrintWriter;  
  9. import java.net.Socket;  
  10. import java.net.UnknownHostException;  
  11.   
  12. /** 
  13.  * 客户端Socket 
  14.  * @author feizi 
  15.  * @time 2014-11-14下午5:18:06 
  16.  */  
  17. public class ClientSocketDemo {  
  18.       
  19.     /** 
  20.      * main测试方法 
  21.      * @param args 
  22.      * @throws UnknownHostException 
  23.      * @throws IOException 
  24.      */  
  25.     public static void main(String[] args) throws UnknownHostException, IOException{  
  26.           
  27.         //创建客户端Socket,向服务器发起请求  
  28. //      String address = "127.0.0.1";  
  29.         String address = "localhost";//服务器地址  
  30.           
  31.         int port = 5555;//端口号  
  32.         Socket socket = new Socket(address, port);  
  33.           
  34.         //获取Socket的字节输出流  
  35.         OutputStream out = socket.getOutputStream();  
  36.           
  37.         //将字节输出流包装成字符打印输出流  
  38.         PrintWriter pw = new PrintWriter(out);  
  39.           
  40. //      pw.print("用户名:admin,密码:123");  
  41. //      pw.print("用户名:tom,密码:456");  
  42. //      pw.print("用户名:dark,密码:789");  
  43. //      pw.print("用户名:white,密码:111");  
  44.         pw.print("用户名:green,密码:222");  
  45.           
  46.         //刷新输出流  
  47.         pw.flush();  
  48.           
  49.         //调用shutDown方法关闭Socket的输出流  
  50.         socket.shutdownOutput();  
  51.           
  52.         //接收服务器端发来的响应信息,获取字节输入流  
  53.         InputStream in = socket.getInputStream();  
  54.           
  55.         //将字节输入流包装成字符输入流  
  56.         InputStreamReader isr = new InputStreamReader(in);  
  57.           
  58.         //为字符输入流添加缓冲  
  59.         BufferedReader br = new BufferedReader(isr);  
  60.           
  61.         //读取字符输入流中的数据信息  
  62.         String data = null;  
  63.         while((data = br.readLine()) != null){  
  64.             System.out.println("我是客户端,服务器说:"+data);  
  65.         }  
  66.           
  67.         //调用shutDown方法关闭Socket的输入流  
  68.         socket.shutdownInput();  
  69.           
  70.         br.close();  
  71.         isr.close();  
  72.         in.close();  
  73.         pw.close();  
  74.         out.close();  
  75.         socket.close();  
  76.     }  
  77. }  
package com.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 客户端Socket
 * @author feizi
 * @time 2014-11-14下午5:18:06
 */
public class ClientSocketDemo {
	
	/**
	 * main测试方法
	 * @param args
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	public static void main(String[] args) throws UnknownHostException, IOException{
		
		//创建客户端Socket,向服务器发起请求
//		String address = "127.0.0.1";
		String address = "localhost";//服务器地址
		
		int port = 5555;//端口号
		Socket socket = new Socket(address, port);
		
		//获取Socket的字节输出流
		OutputStream out = socket.getOutputStream();
		
		//将字节输出流包装成字符打印输出流
		PrintWriter pw = new PrintWriter(out);
		
//		pw.print("用户名:admin,密码:123");
//		pw.print("用户名:tom,密码:456");
//		pw.print("用户名:dark,密码:789");
//		pw.print("用户名:white,密码:111");
		pw.print("用户名:green,密码:222");
		
		//刷新输出流
		pw.flush();
		
		//调用shutDown方法关闭Socket的输出流
		socket.shutdownOutput();
		
		//接收服务器端发来的响应信息,获取字节输入流
		InputStream in = socket.getInputStream();
		
		//将字节输入流包装成字符输入流
		InputStreamReader isr = new InputStreamReader(in);
		
		//为字符输入流添加缓冲
		BufferedReader br = new BufferedReader(isr);
		
		//读取字符输入流中的数据信息
		String data = null;
		while((data = br.readLine()) != null){
			System.out.println("我是客户端,服务器说:"+data);
		}
		
		//调用shutDown方法关闭Socket的输入流
		socket.shutdownInput();
		
		br.close();
		isr.close();
		in.close();
		pw.close();
		out.close();
		socket.close();
	}
}


下面是程序运行结果截图:


客户端:




服务器端:




大家可以点此链接查看单客户端与服务器端交互的情况:

Java网络编程之Socket通信(一)


每天成长一点点,始终坚信:天道酬勤,努力了,奋斗了,一切切有可能!奋斗奋斗奋斗

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值