这里介绍下使用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网络编程案例教程习题参考答案 Java_network_programming是Java编程语言中一个基础组件,用于实现网络通信。以下是Java网络编程案例教程习题参考答案中涉及到的知识点: 1. Socket编程:Socket是Java网络编程...
Java网络编程是Java开发中的重要领域,它涵盖了网络应用程序的设计、实现和调试。在这个主题下,我们可以探讨多个关键知识点: 1. **Java Socket编程**:Java的Socket类提供了基于TCP/IP协议的网络通信能力。通过...
《Java网络编程(第四版)》是一本深入探讨Java在互联网环境下的编程技术的经典书籍。本书旨在帮助读者理解和掌握如何利用Java语言进行高效、安全的网络通信。书中内容覆盖了从基本的网络概念到复杂的多线程编程,是...
Java网络编程是计算机科学中的一个重要领域,特别是在软件开发中,它涉及到如何通过网络进行数据传输和通信。在Java中,网络编程主要依赖于Java的Socket编程、ServerSocket、URL类以及NIO(非阻塞I/O)等核心API。这...
"Java网络编程实验报告" 本实验报告主要介绍了Java网络编程的基本概念和实现方法,通过设计和实现一个简单的客户端/服务器应用程序,了解Java网络编程的基本原理和实现方法。 知识点1:Java 网络编程基础 Java ...
在本资料中,《Java网络编程》第三版提供了深入浅出的讲解,旨在帮助开发者提升对这一领域的理解。 1. **基础概念**: - **网络模型**:Java网络编程基于OSI七层模型和TCP/IP四层模型。理解这些模型有助于理解网络...
《Java网络编程(第4版)》是一本深入探讨Java平台上的网络编程技术的专业书籍,适合想要提升Java通讯技术的学者阅读。此书全面覆盖了Java网络编程的基础和高级概念,帮助开发者理解如何利用Java语言构建高效、可靠的...
Java网络编程
Java 网络编程实践课程设计报告 这是一份 Java 网络编程实践课程设计报告,旨在帮助学生掌握 Java 编程语言、图形化界面、多线程、网络和数据库等技术,并提高动手实践能力和书本知识学习。该课程设计报告涵盖了 ...
Java网络编程是开发分布式应用程序的关键技术,它允许程序通过网络发送和接收数据。《Java网络编程实例》这本书的源代码提供了丰富的示例,帮助读者深入理解这一领域。本压缩包包含的源代码覆盖了Java网络编程的各种...
《Java网络编程精解》是孙卫琴老师的一本经典教程,主要涵盖了Java语言在网络编程领域的深度解析。这本书深入浅出地介绍了如何使用Java进行网络通信,包括基本的TCP/IP协议、套接字编程、多线程技术以及HTTP、FTP等...
Java网络编程是开发分布式应用程序的关键技术,它使得Java程序能够与其他设备、系统和服务进行通信。本书《Java网络编程实例:Java网络编程实例》显然聚焦于通过实际案例来教授这一核心技能。以下是一些主要的知识点...
java网络编程.pdf
Java网络编程是开发分布式应用程序的关键技术,它允许Java程序与其他计算机进行通信,实现数据的交换。这份"Java网络编程资料"包含三个重要的学习资源:关于Socket套接字的"Java套接字编程.chm"、关于网络协议特别是...
本资源为"Java网络编程.chm",是一本关于Java网络编程的电子书,以实例驱动的方式深入讲解了相关知识。 首先,我们要理解Java在网络编程中的基础——IO流。Java中的IO流分为字节流和字符流,它们用于读写数据,包括...
Java网络编程是Java开发中的重要领域,它涵盖了网络通信的所有基本概念和技术,包括TCP/IP协议栈、套接字(Socket)编程、多线程、数据传输格式等。孙卫琴的《java网络编程》一书深入浅出地讲解了这些核心概念,并...
《JAVA网络编程大全》是一本全面且深入介绍Java网络编程技术的权威著作,旨在帮助读者掌握Java在构建网络应用程序中的核心概念和实践技巧。PDF版的书籍为学习者提供了便捷的电子阅读体验,随时随地都能深化对Java...
Java网络编程是Java开发中的重要领域,主要用于实现应用程序之间的通信,包括客户端-服务器架构、分布式系统以及互联网数据传输。这份“java网络编程 PPT”来自清华大学,无疑为学习这一主题提供了权威的参考资料。...
《Java网络编程》是编程领域的经典著作,尤其对于学习Java网络编程的初学者及进阶者来说,这本书具有很高的参考价值。它详细介绍了如何利用Java语言进行网络通信,涵盖了网络编程的基本概念、协议以及实现方法。 一...