`
747017186
  • 浏览: 317469 次
社区版块
存档分类
最新评论

java之网络编程(2)

 
阅读更多

先看一个服务器端单线程处理程序,此服务器端程序是单线程处理的,每次同一个时间只能处理一个请求程序。如果多个客户端并发访问,则排队等待

 

服务端:

package net;

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

public class ServerSocketTest {
	public static void main(String[] args) throws Exception{
		ServerSocket serverSocket = new ServerSocket(10086);//开启10086端口监听
		System.out.println(serverSocket.getLocalPort());
		System.out.println("server start...");
		Socket socket = serverSocket.accept();//服务器已准备,等待客户端连接
		
		InputStream is = socket.getInputStream();//获取客户端输入流
		InputStreamReader isr =new InputStreamReader(is);
		BufferedReader br =new BufferedReader(isr);
		String info =null;
		while((info=br.readLine())!=null){
			System.out.println("我是服务器,客户端说:"+info);
		}
		socket.shutdownInput();//关闭输入流,后续再次调用readLine方法抛异常
		//4、获取输出流,响应客户端的请求
		OutputStream os = socket.getOutputStream();//向客户端输出
		PrintWriter pw = new PrintWriter(os);
		pw.write("欢迎您!");
		pw.flush();


		//5、关闭资源
		pw.close();
		os.close();
		br.close();
		isr.close();
		is.close();
		socket.close();
		serverSocket.close();
	}
}



  

客户端:

package net;

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.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class ClientSocketTest {
	public static void main(String[] args) throws Exception {
		InetAddress address =InetAddress.getLocalHost();
		address.getHostName();//获取计算机名
		address.getHostAddress();//获取IP地址
		System.out.println(address.getHostName());
		System.out.println(address.getHostAddress());
		
		//客户端
		//1、创建客户端Socket,指定服务器地址和端口
		Socket socket =new Socket(address.getHostName(),10086);
		//2、获取输出流,向服务器端发送信息
		OutputStream os = socket.getOutputStream();//字节输出流
		PrintWriter pw =new PrintWriter(os);//将输出流包装成打印流
		pw.write("用户名:admin;密码:123");
		pw.flush();
		socket.shutdownOutput();//关闭输出流,后续再次调用write方法抛异常
		//3、获取输入流,并读取服务器端的响应信息
		InputStream is = socket.getInputStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String info = null;
		while((info=br.readLine()) != null){
		 System.out.println("我是客户端,服务器说:"+info);
		}

		//4、关闭资源
		br.close();
		is.close();
		pw.close();
		os.close();
		socket.close();
	}
}

 

 

============================我是分割线==============================

要想实现服务端可以同时处理多个客户端连接,则必须修改服务器端程序,适应多线程并发。服务端主线程收到一个连接之后直接新开一个线程去处理,主线程继续等到其他客户端连接。

 

服务器:

package net;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ServerSocketTest {
	public static void main(String[] args) throws Exception{
		ServerSocket serverSocket = new ServerSocket(10086);//开启socket服务监听1006端口
		System.out.println("server start...");
		System.out.println("正在监听"+serverSocket.getLocalPort());
		Socket socket = null;
		while(true) {
			socket = serverSocket.accept();//服务器在这阻塞监听,连接到客户端立即开启线程分发处理,提高并发
			serverPool.execute(new ClientHandle(socket));//线程池并发处理
		}
		
//		socket.close();
//		serverSocket.close();
	}
	
	//默认服务器最大并发为5个线程
	private static ExecutorService serverPool = Executors.newFixedThreadPool(5);
}

class ClientHandle implements Runnable{
	private Socket socket;
	public ClientHandle(Socket socket) {
		this.socket = socket;
	}
	
	@Override
	public void run() {
		try {
			InputStream is = socket.getInputStream();
			InputStreamReader isr =new InputStreamReader(is);
			BufferedReader br =new BufferedReader(isr);
			String info = "";
			String temp =null;
			while((temp=br.readLine())!=null){
				info += temp;
				System.out.println("服务器线程"+Thread.currentThread().getName()+"开始处理客户端请求,当前客户端线程:"+temp);
			}
			socket.shutdownInput();//关闭socket输入流,之后再次调用readLine会抛出异常
			//4、获取输出流,响应客户端的请求
			OutputStream os = socket.getOutputStream();
			PrintWriter pw = new PrintWriter(os);
			pw.write("服务器线程"+Thread.currentThread().getName()+"对客户端线程说:"+info+"欢迎您!");
			pw.flush();

			//5、关闭资源
			pw.close();
			os.close();
			br.close();
			isr.close();
			is.close();
			
			Thread.sleep(new Random().nextInt(5000));//模拟服务器处理时间
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

 

客户端:

package net;

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.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ClientSocketTest {
	public static void main(String[] args) throws Exception {
		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
		for(int i= 0 ;i<10;i++) {
			cachedThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					try {
						long startTime = System.currentTimeMillis();
						InetAddress address =InetAddress.getLocalHost();
						address.getHostName();//获取计算机名
						address.getHostAddress();//获取IP地址
						
						//客户端
						//1、创建客户端Socket,指定服务器地址和端口
						Socket socket =new Socket(address.getHostName(),10086);
						//2、获取输出流,向服务器端发送信息
						OutputStream os = socket.getOutputStream();//字节输出流
						PrintWriter pw =new PrintWriter(os);//将输出流包装成打印流
						pw.write(Thread.currentThread().getName());
						pw.flush();
						socket.shutdownOutput();//关闭socket输出流,之后再次调用write方法会抛出异常
						//3、获取输入流,并读取服务器端的响应信息
						InputStream is = socket.getInputStream();
						BufferedReader br = new BufferedReader(new InputStreamReader(is));
						String info = null;
						while((info=br.readLine()) != null){
						 System.out.println(info);
						}
						//4、关闭资源
						br.close();
						is.close();
						pw.close();
						os.close();
						socket.close();
						
						long endTime = System.currentTimeMillis();
						System.out.println("花费时间:"+(endTime-startTime));
					} catch(Exception e) {
						e.printStackTrace();
					}
				}
			});
		}
	}
}

 


 

 当服务器线程资源耗尽的时候,每个连接都必须等到空闲连接,所以花费时间开始变长。

 

 

 

 

  • 大小: 27.2 KB
  • 大小: 30.6 KB
  • 大小: 4.4 KB
  • 大小: 2.5 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics