一、背景
在现代互联网应用中,客户端与服务器之间的通信已成为至关重要的一环。无论是即时通讯、文件传输、云计算还是网络游戏,都需要通过客户端与服务器之间的数据传输来实现。因此,如何实现高效、稳定的客户端与服务器通信技术成为了众多开发者亟需解决的问题。
Java作为一种面向对象、跨平台的编程语言,被广泛应用于互联网应用的开发中。其丰富的库函数和强大的多线程支持使得它成为了一种非常适合实现客户端与服务器通信的编程语言。
本文将介绍Java技术如何实现客户端与服务器之间的通信,包括网络通信的基本原理、Socket编程、以及Java NIO技术。
二、网络通信基础
在了解Java如何实现客户端与服务器通信之前,我们先来介绍一下网络通信的基本原理。
客户端与服务器之间的网络通信主要分为以下两种通信方式:
1.面向连接的通信
面向连接的通信是指在进行通信之前,客户端与服务器之间需要先建立一条连接。在建立连接之后,客户端和服务器之间可以互相发送数据,直到其中一方主动断开连接为止。
面向连接的通信方式可以保证数据传输的可靠性和完整性,但是建立和维护连接需要网络资源和时间,因此不适合对实时性要求比较高的应用场景。
2.无连接的通信
无连接的通信是指客户端和服务器之间直接发送数据,不需要建立和维护连接。由于无连接通信不需要建立和维护连接,所以通信速度比面向连接通信更加快捷,适合对实时性要求比较高的应用场景。
无连接通信在传输过程中可能会出现数据丢失或者传输错误的情况,因此需要在应用层对数据进行一定的校验和纠错处理。
三、Socket编程
Socket(套接字)是实现客户端和服务器之间通信的一种基础技术。在使用Socket进行网络通信时,客户端和服务器之间的通信可以通过TCP或UDP协议进行。
TCP协议使用面向连接的通信方式,可以保障数据传输的可靠性和完整性,但是通信过程中需要建立和维护连接,因此速度较慢。UDP协议使用无连接通信方式,速度快但是不保障数据传输的可靠性和完整性。
Java提供了Socket类和ServerSocket类,分别用于实现客户端和服务器端的Socket编程。
客户端Socket编程模型如下:
“`
Socket clientSocket = new Socket(ip, port); // 创建客户端Socket对象
OutputStream outputStream = clientSocket.getOutputStream(); // 获取输出流
outputStream.write(“hello, server”.getBytes()); // 发送数据
InputStream inputStream = clientSocket.getInputStream(); // 获取输入流
byte[] buff = new byte[1024];
int len = inputStream.read(buff); // 接收服务器返回的数据
clientSocket.close(); // 关闭Socket连接
“`
服务器端Socket编程模型如下:
“`
ServerSocket serverSocket = new ServerSocket(port); // 创建服务器Socket对象
Socket socket = serverSocket.accept(); // 监听端口,等待客户端请求
InputStream inputStream = socket.getInputStream(); // 获取输入流
byte[] buff = new byte[1024];
int len = inputStream.read(buff); // 接收客户端的数据
OutputStream outputStream = socket.getOutputStream(); // 获取输出流
outputStream.write(“hello, client”.getBytes()); // 发送数据给客户端
socket.close(); // 关闭Socket连接
“`
四、Java NIO技术
Java NIO(New Input / Output)是Java 1.4版之后引入的新I/O API,其在Java标准库的java.nio包中。与传统的Java I/O相比,Java NIO具有更快、更灵活、更高效的I/O操作特性。
Java NIO可以实现非阻塞式I/O操作,其底层基于事件驱动机制,可以同时处理多个连接,非常适合实现高并发网络应用。
Java NIO的核心概念主要包括:
1.Buffer 缓冲区
Buffer是Java NIO中的核心类之一,它实现了一个定长数组,并封装了数据读写的操作。常见的Buffer有ByteBuffer、CharBuffer等。
例如,创建一个ByteBuffer对象:
“`
ByteBuffer buffer = ByteBuffer.allocate(1024); // 创建一个Buffer对象
buffer.put(“hello, world”.getBytes()); // 写入数据到Buffer中
buffer.flip(); // 切换Buffer的读写模式
byte[] buff = new byte[buffer.limit()];
buffer.get(buff); // 读取数据
buffer.clear(); // 清空Buffer
“`
2.Channel 通道
Channel是Java NIO中的另一个核心概念,它提供了双向数据传输的功能,可以实现对Buffer中数据的输入和输出。常用的Channel有FileChannel、SocketChannel等。
例如,使用SocketChannel实现客户端与服务器之间的通信:
“`
SocketChannel socketChannel = SocketChannel.open(); // 创建SocketChannel对象
socketChannel.connect(new InetSocketAddress(“127.0.0.1”, port)); // 连接服务器
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put(“hello, server”.getBytes()); // 写入数据到Buffer中
buffer.flip();
socketChannel.write(buffer); // 发送数据给服务器
socketChannel.close(); // 关闭SocketChannel
“`
使用ServerSocketChannel实现服务器端Socket编程:
“`
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 创建ServerSocketChannel对象
serverSocketChannel.socket().bind(new InetSocketAddress(port)); // 监听端口,等待客户端连接
SocketChannel socketChannel = serverSocketChannel.accept(); // 接受客户端连接
ByteBuffer buffer = ByteBuffer.allocate(1024);
socketChannel.read(buffer); // 读取客户端的数据
buffer.flip();
socketChannel.write(buffer); // 发送数据给客户端
socketChannel.close(); // 关闭SocketChannel连接
serverSocketChannel.close(); // 关闭ServerSocketChannel
“`
五、
本文介绍了Java技术如何实现客户端与服务器之间的通信,包括网络通信基础、Socket编程和Java NIO技术。Socket编程是实现客户端和服务器端通信最基础和常规的方法,而Java NIO则是一个性能更高、更灵活、更高效的解决方案。
在实际开发过程中,开发者可以根据应用场景的特点选择合适的通信技术来实现客户端和服务器之间的通信。无论是Socket编程还是Java NIO技术,都需要开发者熟悉其底层实现原理和细节,才能编写出高效、稳定的互联网应用。
相关问题拓展阅读:
- 在java中如何用Socket 进行 服务器端和客户端交互的,具体一点。
- 用Java socket 实现客户端与服务器之间的数据的发送与接受。。。双向的
在java中如何用Socket 进行 服务器端和客户端交互的,具体一点。
打横杠是因为那个方法已经过时了现在已经不怎么用了。。。
Socket 服务器: 1先创侍毕建 ServerSocket ss = new ServerSocket(端口号)
2 接收请求 Socket s = ss.accept()
接收消息 先读后写BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream(),”utf-8″运中));
String str = in.readLine();PrintWriter out = new PrintWriter
( new BufferedWriter( new OutputStreamWriter(s.getOutputStream())),true);
out.println(“服务器信息”);
4关闭流out.close();
in.close();
is.close();
客户端 1、通过IP地址和端口实例化Socket,请求连接服务器
2、获取Socket上的流以进行读写。
3、对流包装进BufferedReader/旁谈山PrintWriters实例
4、关闭打开的流
用Java socket 实现客户端与服务器之间的数据的发送与接受。。。双向的
下面是一个简单的通讯实例,进行Server和Client之间的文件传输。。如果是简单的文本传输的话简化掉文本操作的内容即可。。
1.服务器端
package sterning;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerTest {
int port = 8821;
void start() {
Socket s = null;
try {
ServerSocket ss = new ServerSocket(port);
while (true) {
// 选择进行传输的文件
String filePath = “D:\\lib.rar”;
File fi = new File(filePath);
System.out.println(“文件长度:” + (int) fi.length());
// public Socket accept() throws
// IOException侦听并接受携笑到此套接字的连接。此方法在进行连接之前一直阻塞。
s = ss.accept();
System.out.println(“建立socket链接”);
DataInputStream dis = new DataInputStream(new BufferedInputStream(s.getInputStream()));
dis.readByte();
DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
DataOutputStream ps = new DataOutputStream(s.getOutputStream());
//将文件名及长度传给客户端。这里要真正适用所有平台,例如拍拿中文名的处理,还需要加工,具体可袭隐搭以参见Think In Java 4th里有现成的代码。
ps.writeUTF(fi.getName());
ps.flush();
ps.writeLong((long) fi.length());
ps.flush();
int bufferSize = 8192;
byte buf = new byte;
while (true) {
int read = 0;
if (fis != null) {
read = fis.read(buf);
}
if (read == -1) {
break;
}
ps.write(buf, 0, read);
}
ps.flush();
// 注意关闭socket链接哦,不然客户端会等待server的数据过来,
// 直到socket超时,导致数据不完整。
fis.close();
s.close();
System.out.println(“文件传输完成”);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String arg) {
new ServerTest().start();
}
}
2.socket的Util辅助类
package sterning;
import java.net.*;
import java.io.*;
public class ClientSocket {
private String ip;
private int port;
private Socket socket = null;
DataOutputStream out = null;
DataInputStream getMessageStream = null;
public ClientSocket(String ip, int port) {
this.ip = ip;
this.port = port;
}
/** *//**
* 创建socket连接
*
* @throws Exception
*exception
*/
public void CreateConnection() throws Exception {
try {
socket = new Socket(ip, port);
} catch (Exception e) {
e.printStackTrace();
if (socket != null)
socket.close();
throw e;
} finally {
}
}
public void sendMessage(String sendMessage) throws Exception {
try {
out = new DataOutputStream(socket.getOutputStream());
if (sendMessage.equals(“Windows”)) {
out.writeByte(0x1);
out.flush();
return;
}
if (sendMessage.equals(“Unix”)) {
out.writeByte(0x2);
out.flush();
return;
}
if (sendMessage.equals(“Linux”)) {
out.writeByte(0x3);
out.flush();
} else {
out.writeUTF(sendMessage);
out.flush();
}
} catch (Exception e) {
e.printStackTrace();
if (out != null)
out.close();
throw e;
} finally {
}
}
public DataInputStream getMessageStream() throws Exception {
try {
getMessageStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
return getMessageStream;
} catch (Exception e) {
e.printStackTrace();
if (getMessageStream != null)
getMessageStream.close();
throw e;
} finally {
}
}
public void shutDownConnection() {
try {
if (out != null)
out.close();
if (getMessageStream != null)
getMessageStream.close();
if (socket != null)
socket.close();
} catch (Exception e) {
}
}
}
3.客户端
package sterning;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class ClientTest {
private ClientSocket cs = null;
private String ip = “localhost”;// 设置成服务器IP
private int port = 8821;
private String sendMessage = “Windwos”;
public ClientTest() {
try {
if (createConnection()) {
sendMessage();
getMessage();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private boolean createConnection() {
cs = new ClientSocket(ip, port);
try {
cs.CreateConnection();
System.out.print(“连接服务器成功!” + “\n”);
return true;
} catch (Exception e) {
System.out.print(“连接服务器失败!” + “\n”);
return false;
}
}
private void sendMessage() {
if (cs == null)
return;
try {
cs.sendMessage(sendMessage);
} catch (Exception e) {
System.out.print(“发送消息失败!” + “\n”);
}
}
private void getMessage() {
if (cs == null)
return;
DataInputStream inputStream = null;
try {
inputStream = cs.getMessageStream();
} catch (Exception e) {
System.out.print(“接收消息缓存错误\n”);
return;
}
try {
//本地保存路径,文件名会自动从服务器端继承而来。
String savePath = “E:\\”;
int bufferSize = 8192;
byte buf = new byte;
int passedlen = 0;
long len=0;
savePath += inputStream.readUTF();
DataOutputStream fileOut = new DataOutputStream(new BufferedOutputStream(newBufferedOutputStream(new FileOutputStream(savePath))));
len = inputStream.readLong();
System.out.println(“文件的长度为:” + len + “\n”);
System.out.println(“开始接收文件!” + “\n”);
while (true) {
int read = 0;
if (inputStream != null) {
read = inputStream.read(buf);
}
passedlen += read;
if (read == -1) {
break;
}
//下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
System.out.println(“文件接收了” + (passedlen * 100/ len) + “%\n”);
fileOut.write(buf, 0, read);
}
System.out.println(“接收完成,文件存为” + savePath + “\n”);
fileOut.close();
} catch (Exception e) {
System.out.println(“接收消息错误” + “\n”);
return;
}
}
public static void main(String arg) {
new ClientTest();
}
}
《Ja av程序设猛春桐计枝坦实用教程》第2版 第11章第三节 86页 socket编程,一个简单的森睁例子,server和client简单双向发送信息。。。
服务器:
ServerSocket ss=new ServerSocket(9999);
Socket s=ss.accept();
OutputStream os=s.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
String temp = “Hello”镇乱厅御隐陪滑;
dos.write(temp.getBytes());
dos.flush();
客户端:
Socket s=new Socket(“127.0.0.1”,9999);
s.setSoTimeout(3000);
OutputStream os=s.getOutputStream();
InputStream is=s.getInputStream();
BufferedReader inBr = new BufferedReader(new InputStreamReader(Is));
int buffLength = 1024;
char buff = new char;
int readLength = 0;
StringBuilder = new StringBuilder();
String strs = null;
while((readLength = inBr.read(buff)) > 0){
Buffer buffer = null;
String str = new String (buff, 0 ,readLength);
System.out.println(str);
java服务器与客户端通信的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java服务器与客户端通信,Java技术实现服务器与客户端通信,在java中如何用Socket 进行 服务器端和客户端交互的,具体一点。,用Java socket 实现客户端与服务器之间的数据的发送与接受。。。双向的的信息别忘了在本站进行查找喔。