java中socket包边界结束标记_Java中的Socket编程(2)-提高

本文介绍了如何使用Java实现一个服务端和客户端同时读写的Socket程序。通过设定'eof'作为数据包边界结束标记,使得双方能正确识别数据传输的完成。详细分析了服务端和客户端的代码流程,以及为何需要设置结束标记的原因。
摘要由CSDN通过智能技术生成

[size=medium]

[b]日日行,不怕千万里;常常做,不怕千万事。[/b]

意思是说,每天都走路的话,就不怕走千里万里,每天都做事的话,就不怕做了千事万事。学习也一样,每天学一点,就不怕学习了千万知识。

上一次我们对Socket编程有了一个初步的了解,今天我们来继续学习。上一次我们写了一个简单的服务端和客户端程序,只是实现了客户端写,服务端读。今天我们来实现一个服务端和客户端同时读写的程序。

[b]需求:实现一个服务端和客户端同时读写。[/b]

为了便于大家更好的理解,我画了一个程序流程图,虽然不是很专业和美观,但旨在说明问题。

[b]1、程序流程图:[/b]

[img]http://dl2.iteye.com/upload/attachment/0095/9910/64ca9221-8c77-35b7-92fc-cad0b36523e3.jpg[/img]

[b]2、代码实现:[/b]

[b]1)服务端代码:[/b]

[/size]

/**

* 服务端

* 需求:服务端和客户端同时读写

* @author Sam

*

*/

public class EnhanceServer {

/**

* @param args

*/

public static void main(String[] args) {

try {

// 创建一个服务端ServerSocket,监听指定端口的请求

ServerSocket ss = new ServerSocket(9999);

System.out.println("Server 等待客户端接入...");

// 监听客户端请求

Socket socket = ss.accept();

// 与客户端建立连接之后,读取客户端发过来的信息

InputStream is = socket.getInputStream();

byte[] buffer = new byte[1024];

int len = 0;

// 定义一个字符串构建器,用于存储客户端发过来的数据

StringBuilder sBuilder = new StringBuilder();

int index;

while ( (len=is.read(buffer)) != -1 ) {

String temp = new String(buffer, 0, len);

// 读到结束符,则跳出循环

if ( (index=temp.indexOf("eof")) != -1 ) {

// 截取指定长度

sBuilder.append(temp.substring(0, index));

break;

}

// 如果没有读到结束符,则继续读取,并加入字符串构建器

sBuilder.append(temp);

}

System.out.println("Server 来自客户端的信息 : " + sBuilder.toString());

// 读完之后,往客户端发送响应数据

OutputStream out = socket.getOutputStream();

out.write("Hello Client!".getBytes());

out.write("eof".getBytes());// 写一个结束符

out.flush();

out.close();

is.close();

socket.close();

ss.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

[size=medium]

[b]服务端代码分析:[/b]

[b]1)代码流程:[/b]服务端先读取客户端发送过来的数据,然后输出在控制台中,读完之后,接着往客户端写一段回应数据。

前面我们提到服务端在监听客户端请求时,使用的accept方法是阻塞方法;

[b]2)问题原因:[/b]在这里while循环判断条件中的read方法也是阻塞式操作的,也就是说while循环判断条件中当读到数据时,就会执行循环体,否则就一直处于阻塞状态,这样后面的代码就永远无法执行了。

[b]3)解决方案:[/b]所以,我们通常都会约定一个结束标记,当服务端读到客户端发送过来的数据包含结束标记时,服务端就会跳出循环,接着执行往下的代码。

在这里我们约定结束标记为eof,每次写完数据都要写一个结束标记!

[b]2)客户端代码:[/b]

[/size]

/**

* 客户端

* @author Sam

*

*/

public class EnhanceClient {

/**

* @param args

*/

public static void main(String[] args) {

try {

// 与服务端建立连接(服务端主机号,服务端监听的端口号)

Socket socket = new Socket("127.0.0.1", 9999);

// 与服务端建立连接之后,就可以往服务端写数据

OutputStream out = socket.getOutputStream();

// 往服务端中写数据

out.write("Hello Server!".getBytes());

out.write("eof".getBytes());// 写一个结束符,表示写入完毕

out.flush();

// 写完之后,获取服务端的响应数据

InputStream is = socket.getInputStream();

byte[] buffer = new byte[1024];

int len = 0;

// 定义一个StringBuilder存储客户端发过来的数据

StringBuilder sBuilder = new StringBuilder();

int index;

while ( (len=is.read(buffer)) != -1 ) {

String temp = new String(buffer, 0, len);

// 读到结束符,则跳出循环

if ( (index=temp.indexOf("eof")) != -1) {

sBuilder.append(temp.substring(0, index));

break;

}

sBuilder.append(temp);

}

System.out.println("Client 来自服务端的信息 : " + sBuilder.toString());

out.close();

is.close();

socket.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

[size=medium]

[b]客户端代码分析:[/b]

1)[b]代码流程:[/b]

客户端往服务端写一段数据,写完之后,接着读取服务端返回的响应数据,并输出在控制台中。

[b]2)问题原因:[/b]

同理,客户端发送数据完毕后,往流中写一个结束标记符告诉服务端数据已经发送完毕。

[b]3、运行结果:[/b]

注意:先运行Server程序,再运行Client程序。结果如下:

[b]1)Server程序控制台:[/b]

[img]http://dl2.iteye.com/upload/attachment/0095/9933/0f9e59ac-4cf6-313f-8f6e-74d59f160ac7.jpg[/img]

[b]2)Client程序控制台:[/b]

[img]http://dl2.iteye.com/upload/attachment/0095/9935/739f9e69-4ec3-394d-afef-d8ebcc6329dc.jpg[/img]

[b]4、总结:[/b]

这便是服务端和客户端同时通信的程序。客户端发送数据给服务端,服务端收到数据之后再返回相应的结果给客户端。

[/size]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值