关闭

Java网络编程——基于TCP的Socket编程

标签: java网络编程socket多线程tcp
257人阅读 评论(0) 收藏 举报
分类:

一、基于TCP的Socket通信

1、TCP协议:TCP协议是面向连接的、可靠的、有序的,以字节流方式传输数据的通信协议。客户端与服务器要想实现通信,首先需要建立连接。

2、Java提供的基于TCP协议实现网络通信的类为:客户端的Socket类、服务器端的ServerSocket类。

3、Socket通信模型,见下图(摘自慕课网)


4、Socket通信的实现步骤:

(1)创建ServerSocket和Socket对象

(2)打开Socket的输入/输出流

(3)从输入/输出流中读/写数据

(4)关闭相关资源


二、Socket编程实例

1、非多线程的情况

服务器端:

ServerDemo.java

public class ServerDemo {
	public static void main(String[] args) throws IOException {
		ServerSocket server = null;
		Socket client = null;
		InputStream in = null;
		InputStreamReader reader = null;
		BufferedReader bufReader = null;
		OutputStream out = null;
		PrintWriter writer = null;
		
		try {
			//1、创建服务器端socket,并绑定9999端口,绑定端口之后,服务器一直监听9999端口的请求
			server = new ServerSocket(9999);
			System.out.println("------服务器已启动,等待客户端信息------");
			//2、服务器端接收到客户端的请求,建立连接
			client = server.accept();
			
			//3、将客户的请求数据以输入流的形式读取出来
			in = client.getInputStream();
			reader = new InputStreamReader(in);
			bufReader = new BufferedReader(reader);
			String msg = null;
			while((msg = bufReader.readLine()) != null) {
				System.out.println("收到客户端的信息:" + msg);
			}
			//4、关闭输入流
			client.shutdownInput();
			
			//5、通过输出流向客户端发送信息
			out = client.getOutputStream();
			writer = new PrintWriter(out);
			writer.write("我是服务器,我已经收到了你的信息!");
			writer.flush();
			//6、关闭输出流
			client.shutdownOutput();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//7、程序最后一定要关闭资源
			if(in != null)
				in.close();
			if(reader != null) 
				reader.close();
			if(bufReader != null)
				bufReader.close();
			if(out != null)
				out.close();
			if(writer != null)
				writer.close();
			if(client != null)
				client.close();
			if(server != null)
				server.close();
		}
	}
}
客户端:

ClientDemo.java

public class ClientDemo {
	public static void main(String[] args) throws IOException {
		Socket client = null;
		InputStream in = null;
		InputStreamReader reader = null;
		BufferedReader bufReader = null;
		OutputStream out = null;
		PrintWriter writer = null;
		
		try {
			 //1、新建客户端socket,指明需要连接的服务器地址和端口号
			 //如果是本机,地址可以是localhost或者127.0.0.1
			client = new Socket("localhost", 9999);
			System.out.println("------客户端准备与服务器端建立连接------");
			
			//2、建立连接后通过输出流向服务器端发送信息
			out = client.getOutputStream();
			writer = new PrintWriter(out);
			writer.write("我是客户端,你收到我的请求了吗?");
			writer.flush();
			//3、关闭输出流
			client.shutdownOutput();
			
			//4、将服务器端的响应以输出流的形式读取出来
			in = client.getInputStream();
			reader = new InputStreamReader(in);
			bufReader = new BufferedReader(reader);
			String msg = null;
			while((msg = bufReader.readLine()) != null) {
				System.out.println("收到服务器的应答:" + msg);
			}
			//5、关闭输出流
			client.shutdownInput();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//6、程序的最后一定要关闭资源
			if(in != null)
				in.close();
			if(reader != null) 
				reader.close();
			if(bufReader != null)
				bufReader.close();
			if(out != null)
				out.close();
			if(writer != null)
				writer.close();
			if(client != null)
				client.close();
		}
	}
}

2、多线程的情况(即一个服务器端可以不断接收多个客户端的请求)

服务器端入口:

ServerThreadMain.java

public class ServerThreadMain {
	public static void main(String[] args) {
		ServerSocket server = null;
		Socket client = null;
		try {
			server = new ServerSocket(9999);
			System.out.println("------服务器已启动,等待客户端信息------");

			while(true) {
				client = server.accept();
				ServerThread thread = new ServerThread(client);
				thread.start();
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

这里写了一个死循环,代表服务器端一直接收客户端的请求,每接收到一个客户端请求,服务器端会新启一个线程进行处理。

代表服务器端核心处理的线程:

ServerThread.java

public class ServerThread extends Thread {
	public Socket client;
	
	public ServerThread(Socket client) {
		this.client = client;
	}
	
	public void run() {
		InputStream in = null;
		InputStreamReader reader = null;
		BufferedReader bufReader = null;
		OutputStream out = null;
		PrintWriter writer = null;
		
		try {			
			in = client.getInputStream();
			reader = new InputStreamReader(in);
			bufReader = new BufferedReader(reader);
			String msg = null;
			while((msg = bufReader.readLine()) != null) {
				System.out.println("收到客户端的信息:" + msg);
			}
			client.shutdownInput();
			
			out = client.getOutputStream();
			writer = new PrintWriter(out);
			writer.write("我是服务器,我已经收到了你的信息!");
			writer.flush();
			client.shutdownOutput();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(in != null)
					in.close();
				if(reader != null) 
					reader.close();
				if(bufReader != null)
					bufReader.close();
				if(out != null)
					out.close();
				if(writer != null)
					writer.close();
				if(client != null)
					client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
客户端代码与非多线程的客户端代码相同,不再赘述。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:30050次
    • 积分:715
    • 等级:
    • 排名:千里之外
    • 原创:42篇
    • 转载:1篇
    • 译文:0篇
    • 评论:5条
    最新评论