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

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

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


下面直接贴代码吧:


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

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


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


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,这个和单客户端的情况一样,在第一篇中有详细介绍


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通信(一)


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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值