`
berdy
  • 浏览: 514207 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java 网络编程

阅读更多
这里介绍下使用java的socket编程,搭建一个server与client的通信框架。先看一段代码:

Server端
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TestServer {

	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		Socket socket = null;
		InputStream inStream = null;

		try {
			serverSocket = new ServerSocket(8080);
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {
			if (serverSocket != null) {
				// 线程将阻塞在此直到有客户端来连接
				socket = serverSocket.accept();
				
				//处理与客户端的通信逻辑
				System.out.println("a client connected");
				inStream = socket.getInputStream();
				byte[] buff = new byte[8];
				// 阻塞在这里直到有数据可以读取或者流结束也或者异常出现
				int len = inStream.read(buff);
				System.out.println("server read " + len + " bytes");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (inStream != null) {
				try {
					inStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (serverSocket != null) {
				try {
					serverSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
}


Client端
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class TestClient {

	public static void main(String[] args) {
		Socket socket = null;
		OutputStream out = null;
		try {
			// socket创建中就连接了服务器端,服务器端的accept()将不再阻塞
			socket = new Socket("localhost", 8080);
			out = socket.getOutputStream();
			// 在此行设置断点可以看到服务端一直阻塞在read方法调用上
			out.write("hello world".getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}
}


上面的例子中Server端只是处理了与一个client端的通信,一旦有一个client与server连接上后,server端将不再接收其他client的连接了。如果想不断的接收其他client的连接,可以把accept()方法调用放到一个循环中。
while (true) {
	// 线程将阻塞在此直到有客户端来连接
	socket = serverSocket.accept();
	
	//处理与客户端的通信逻辑
	System.out.println("client "
			+ socket.getRemoteSocketAddress() + " connected");
	inStream = socket.getInputStream();
	byte[] buff = new byte[8];
	// 阻塞在这里直到有数据可以读取或者流结束也或者异常出现
	int len = inStream.read(buff);
	System.out.println("server read " + len + " bytes");
}


这样服务器端就可以一直运行,只要在可用端口数的限制内,每个client都能与server建立连接。上面的代码只是搭建了一个基本的server与client通信的框架,要想完成一个可以商用的通信框架还需要做很多的工作。首当其冲的就是当客户端增多后,如何能快速的响应客户端的请求?
如果上面代码中通过ServerSocket.accept()获取到与client socket通信的server端socket后,如果与每个client通信的逻辑比较复杂耗时呢?也就是while 的每次循环都执行长时间,那么将有很多client的连接请求被阻塞,很多client会出现超时异常。对于这种情况,很自然的一个想法就是使用多线程,将与client通信的逻辑放到其他线程中处理,主线程只负责与client建立连接。
对server端代码做调整如下:
public static void main(String[] args) {
	ServerSocket serverSocket = null;

	try {
		serverSocket = new ServerSocket(8080);
	} catch (IOException e) {
		e.printStackTrace();
	}

	try {
		if (serverSocket != null) {
			while (true) {
				// 线程将阻塞在此直到有客户端来连接
				Socket socket = serverSocket.accept();
				// 针对每个线程另开线程处理通信逻辑
				process(socket);
			}
		}
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
		if (serverSocket != null) {
			try {
				serverSocket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

public static void process(final Socket socket) {
	new Thread(new Runnable() {
		public void run() {
			InputStream inStream = null;
			System.out.println("client " + socket.getRemoteSocketAddress()
					+ " connected");
			try {
				inStream = socket.getInputStream();
				byte[] buff = new byte[8];
				// 阻塞在这里直到有数据可以读取或者流结束也或者异常出现
				int len = inStream.read(buff);
				System.out.println("server read " + len + " bytes");
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (inStream != null) {
					try {
						inStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}).start();

}


看到这里,肯定有人能发现问题了,如果有1000个client来连接,岂不是开1000个线程来处理,服务器的资源消耗将会直线上升(创建线程本身要消耗资源,线程之间的上下文频繁切换也消耗资源)。如何解决呢?线程池,对于优化高并发,对象池化是个神器。jdk中就提供了线程池,拿来主义,对服务器端代码修改如下:

private static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime()
				.availableProcessors() * 2);;

//...

public static void process(final Socket socket) {
	executorService.execute(new Runnable() {
		public void run() {
			InputStream inStream = null;
			System.out.println("client " + socket.getRemoteSocketAddress()
					+ " connected");
			try {
				inStream = socket.getInputStream();
				byte[] buff = new byte[8];
				// 阻塞在这里直到有数据可以读取或者流结束也或者异常出现
				int len = inStream.read(buff);
				System.out.println("server read " + len + " bytes");
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (inStream != null) {
					try {
						inStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	});
}


弄到现在,一个像样地server与client的通信框架已成雏形,当然距离稳定,可扩展还有很远的距离。


分享到:
评论

相关推荐

    Java网络编程案例教程习题参考答案 .pdf

    Java网络编程案例教程习题参考答案 Java_network_programming是Java编程语言中一个基础组件,用于实现网络通信。以下是Java网络编程案例教程习题参考答案中涉及到的知识点: 1. Socket编程:Socket是Java网络编程...

    Java网络编程/Java网络编程实例

    Java网络编程是Java开发中的重要领域,它涵盖了网络应用程序的设计、实现和调试。在这个主题下,我们可以探讨多个关键知识点: 1. **Java Socket编程**:Java的Socket类提供了基于TCP/IP协议的网络通信能力。通过...

    java网络编程第四版pdf

    《Java网络编程(第四版)》是一本深入探讨Java在互联网环境下的编程技术的经典书籍。本书旨在帮助读者理解和掌握如何利用Java语言进行高效、安全的网络通信。书中内容覆盖了从基本的网络概念到复杂的多线程编程,是...

    Java网络编程期末考试复习题库+答案

    Java网络编程是计算机科学中的一个重要领域,特别是在软件开发中,它涉及到如何通过网络进行数据传输和通信。在Java中,网络编程主要依赖于Java的Socket编程、ServerSocket、URL类以及NIO(非阻塞I/O)等核心API。这...

    Java网络编程实验报告.pdf

    "Java网络编程实验报告" 本实验报告主要介绍了Java网络编程的基本概念和实现方法,通过设计和实现一个简单的客户端/服务器应用程序,了解Java网络编程的基本原理和实现方法。 知识点1:Java 网络编程基础 Java ...

    java网络编程

    在本资料中,《Java网络编程》第三版提供了深入浅出的讲解,旨在帮助开发者提升对这一领域的理解。 1. **基础概念**: - **网络模型**:Java网络编程基于OSI七层模型和TCP/IP四层模型。理解这些模型有助于理解网络...

    Java网络编程(第4版)PDF

    《Java网络编程(第4版)》是一本深入探讨Java平台上的网络编程技术的专业书籍,适合想要提升Java通讯技术的学者阅读。此书全面覆盖了Java网络编程的基础和高级概念,帮助开发者理解如何利用Java语言构建高效、可靠的...

    [Java网络编程(第3版,2004)].(Java.Network.Prog.epub

    Java网络编程

    Java网络编程实践课程设计报告.pdf

    Java 网络编程实践课程设计报告 这是一份 Java 网络编程实践课程设计报告,旨在帮助学生掌握 Java 编程语言、图形化界面、多线程、网络和数据库等技术,并提高动手实践能力和书本知识学习。该课程设计报告涵盖了 ...

    Java网络编程实例(随书源代码)

    Java网络编程是开发分布式应用程序的关键技术,它允许程序通过网络发送和接收数据。《Java网络编程实例》这本书的源代码提供了丰富的示例,帮助读者深入理解这一领域。本压缩包包含的源代码覆盖了Java网络编程的各种...

    Java网络编程精解(孙卫琴)电子教案

    《Java网络编程精解》是孙卫琴老师的一本经典教程,主要涵盖了Java语言在网络编程领域的深度解析。这本书深入浅出地介绍了如何使用Java进行网络通信,包括基本的TCP/IP协议、套接字编程、多线程技术以及HTTP、FTP等...

    java网络编程.pdf

    java网络编程.pdf

    《Java网络编程实例:Java网络编程实例》

    Java网络编程是开发分布式应用程序的关键技术,它使得Java程序能够与其他设备、系统和服务进行通信。本书《Java网络编程实例:Java网络编程实例》显然聚焦于通过实际案例来教授这一核心技能。以下是一些主要的知识点...

    Java网络编程资料

    Java网络编程是开发分布式应用程序的关键技术,它允许Java程序与其他计算机进行通信,实现数据的交换。这份"Java网络编程资料"包含三个重要的学习资源:关于Socket套接字的"Java套接字编程.chm"、关于网络协议特别是...

    Java网络编程.chm

    本资源为"Java网络编程.chm",是一本关于Java网络编程的电子书,以实例驱动的方式深入讲解了相关知识。 首先,我们要理解Java在网络编程中的基础——IO流。Java中的IO流分为字节流和字符流,它们用于读写数据,包括...

    java网络编程源码

    Java网络编程是Java开发中的重要领域,它涵盖了网络通信的所有基本概念和技术,包括TCP/IP协议栈、套接字(Socket)编程、多线程、数据传输格式等。孙卫琴的《java网络编程》一书深入浅出地讲解了这些核心概念,并...

    JAVA网络编程大全,pdf版

    《JAVA网络编程大全》是一本全面且深入介绍Java网络编程技术的权威著作,旨在帮助读者掌握Java在构建网络应用程序中的核心概念和实践技巧。PDF版的书籍为学习者提供了便捷的电子阅读体验,随时随地都能深化对Java...

    java网络编程 PPT

    Java网络编程是Java开发中的重要领域,主要用于实现应用程序之间的通信,包括客户端-服务器架构、分布式系统以及互联网数据传输。这份“java网络编程 PPT”来自清华大学,无疑为学习这一主题提供了权威的参考资料。...

    java网络编程经典的学习书籍

    《Java网络编程》是编程领域的经典著作,尤其对于学习Java网络编程的初学者及进阶者来说,这本书具有很高的参考价值。它详细介绍了如何利用Java语言进行网络通信,涵盖了网络编程的基本概念、协议以及实现方法。 一...

Global site tag (gtag.js) - Google Analytics