Java编程那些事儿106——网络编程技术5
陈跃峰
出自:http://blog.csdn.net/mailbomb
该示例的功能是实现将客户端程序的系统时间发送给服务器端,服务器端接收到时间以后,向客户端反馈字符串“OK”。实现该功能的客户端代码如下所示:
package udp;
import java.net.*;
import java.util.*;
/**
* 简单的UDP客户端,实现向服务器端发生系统时间功能
*/
public class SimpleUDPClient {
public static void main(String[] args) {
DatagramSocket ds = null; //连接对象
DatagramPacket sendDp; //发送数据包对象
DatagramPacket receiveDp; //接收数据包对象
String serverHost = "127.0.0.1"; //服务器IP
int serverPort = 10010; //服务器端口号
try{
//建立连接
ds = new DatagramSocket();
//初始化发送数据
Date d = new Date(); //当前时间
String content = d.toString(); //转换为字符串
byte[] data = content.getBytes();
//初始化发送包对象
InetAddress address = InetAddress.getByName(serverHost);
sendDp = new DatagramPacket(data,data.length,address,serverPort);
//发送
ds.send(sendDp);
//初始化接收数据
byte[] b = new byte[1024];
receiveDp = new DatagramPacket(b,b.length);
//接收
ds.receive(receiveDp);
//读取反馈内容,并输出
byte[] response = receiveDp.getData();
int len = receiveDp.getLength();
String s = new String(response,0,len);
System.out.println("服务器端反馈为:" + s);
}catch(Exception e){
e.printStackTrace();
}finally{
try{
//关闭连接
ds.close();
}catch(Exception e){}
}
}
}
在该示例代码中,首先建立UDP方式的网络连接,然后获得当前系统时间,这里获得的系统时间是客户端程序运行的本地计算机的时间,然后将时间字符串以及服务器端的IP和端口,构造成发送数据包对象,调用连接对象ds的send方法发送出去。在数据发送出去以后,构造接收数据的数据包对象,调用连接对象ds的receive方法接收服务器端的反馈,并输出在控制台。最后在finally语句块中关闭客户端网络连接。
和下面将要介绍的服务器端一起运行时,客户端程序的输出结果为:
服务器端反馈为:OK
下面是该示例程序的服务器端代码实现:
package udp;
import java.net.*;
/**
* 简单UDP服务器端,实现功能是输出客户端发送数据,
并反馈字符串“OK"给客户端
*/
public class SimpleUDPServer {
public static void main(String[] args) {
DatagramSocket ds = null; //连接对象
DatagramPacket sendDp; //发送数据包对象
DatagramPacket receiveDp; //接收数据包对象
final int PORT = 10010; //端口
try{
//建立连接,监听端口
ds = new DatagramSocket(PORT);
System.out.println("服务器端已启动:");
//初始化接收数据
byte[] b = new byte[1024];
receiveDp = new DatagramPacket(b,b.length);
//接收
ds.receive(receiveDp);
//读取反馈内容,并输出
InetAddress clientIP = receiveDp.getAddress();
int clientPort = receiveDp.getPort();
byte[] data = receiveDp.getData();
int len = receiveDp.getLength();
System.out.println("客户端IP:" + clientIP.getHostAddress());
System.out.println("客户端端口:" + clientPort);
System.out.println("客户端发送内容:" + new String(data,0,len));
//发送反馈
String response = "OK";
byte[] bData = response.getBytes();
sendDp = new DatagramPacket(bData,bData.length,clientIP,clientPort);
//发送
ds.send(sendDp);
}catch(Exception e){
e.printStackTrace();
}finally{
try{
//关闭连接
ds.close();
}catch(Exception e){}
}
}
}
在该服务器端实现中,首先监听10010号端口,和TCP方式的网络编程类似,服务器端的receive方法是阻塞方法,如果客户端不发送数据,则程序会在该方法处阻塞。当客户端发送数据到达服务器端时,则接收客户端发送过来的数据,然后将客户端发送的数据内容读取出来,并在服务器端程序中打印客户端的相关信息,从客户端发送过来的数据包中可以读取出客户端的IP以及客户端端口号,将反馈数据字符串“OK”发送给客户端,最后关闭服务器端连接,释放占用的系统资源,完成程序功能示例。
和前面TCP方式中的网络编程类似,这个示例也仅仅是网络编程的功能示例,也存在前面介绍的客户端无法进行多次数据交换,以及服务器端不支持多个客户端的问题,这两个问题也需要对于代码进行处理才可以很方便的进行解决。
在解决该问题以前,需要特别指出的是UDP方式的网络编程由于不建立虚拟的连接,所以在实际使用时和TCP方式存在很多的不同,最大的一个不同就是“无状态”。该特点指每次服务器端都收到信息,但是这些信息和连接无关,换句话说,也就是服务器端只是从信息是无法识别出是谁发送的,这样就要求发送信息时的内容需要多一些,这个在后续的示例中可以看到。
下面是实现客户端多次发送以及服务器端支持多个数据包同时处理的程序结构,实现的原理和TCP方式类似,在客户端将数据的发送和接收放入循环中,而服务器端则将接收到的每个数据包启动一个专门的线程进行处理。实现的代码如下:
package udp;
import java.net.*;
import java.util.*;
/**
* 简单的UDP客户端,实现向服务器端发生系统时间功能
* 该程序发送3次数据到服务器端
*/
public class MulUDPClient {
public static void main(String[] args) {
DatagramSocket ds = null; //连接对象
DatagramPacket sendDp; //发送数据包对象
DatagramPacket receiveDp; //接收数据包对象
String serverHost = "127.0.0.1"; //服务器IP
int serverPort = 10012; //服务器端口号
try{
//建立连接
ds = new DatagramSocket();
//初始化
InetAddress address = InetAddress.getByName(serverHost);
byte[] b = new byte[1024];
receiveDp = new DatagramPacket(b,b.length);
System.out.println("客户端准备完成");
//循环30次,每次间隔0.01秒
for(int i = 0;i < 30;i++){
//初始化发送数据
Date d = new Date(); //当前时间
String content = d.toString(); //转换为字符串
byte[] data = content.getBytes();
//初始化发送包对象
sendDp = new DatagramPacket(data,data.length,address, serverPort);
//发送
ds.send(sendDp);
//延迟
Thread.sleep(10);
//接收
ds.receive(receiveDp);
//读取反馈内容,并输出
byte[] response = receiveDp.getData();
int len = receiveDp.getLength();
String s = new String(response,0,len);
System.out.println("服务器端反馈为:" + s);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
//关闭连接
ds.close();
}catch(Exception e){}
}
}
}
在该示例中,将和服务器端进行数据交换的逻辑写在一个for循环的内部,这样就可以实现和服务器端的多次交换了,考虑到服务器端的响应速度,在每次发送之间加入0.01秒的时间间隔。最后当数据交换完成以后关闭连接,结束程序。
实现该逻辑的服务器端程序代码如下:
package udp;
import java.net.*;
/**
* 可以并发处理数据包的服务器端
* 功能为:显示客户端发送的内容,并向客户端反馈字符串“OK”
*/
public class MulUDPServer {
public static void main(String[] args) {
DatagramSocket ds = null; //连接对象
DatagramPacket receiveDp; //接收数据包对象
final int PORT = 10012; //端口
byte[] b = new byte[1024];
receiveDp = new DatagramPacket(b,b.length);
try{
//建立连接,监听端口
ds = new DatagramSocket(PORT);
System.out.println("服务器端已启动:");
while(true){
//接收
ds.receive(receiveDp);
//启动线程处理数据包
new LogicThread(ds,receiveDp);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
//关闭连接
ds.close();
}catch(Exception e){}
}
}
}
该代码实现了服务器端的接收逻辑,使用一个循环来接收客户端发送过来的数据包,当接收到数据包以后启动一个LogicThread线程处理该数据包。这样服务器端就可以实现同时处理多个数据包了。
实现逻辑处理的线程代码如下:
package udp;
import java.net.*;
/**
* 逻辑处理线程
*/
public class LogicThread extends Thread {
/**连接对象*/
DatagramSocket ds;
/**接收到的数据包*/
DatagramPacket dp;
public LogicThread(DatagramSocket ds,DatagramPacket dp){
this.ds = ds;
this.dp = dp;
start(); //启动线程
}
public void run(){
try{
//获得缓冲数组
byte[] data = dp.getData();
//获得有效数据长度
int len = dp.getLength();
//客户端IP
InetAddress clientAddress = dp.getAddress();
//客户端端口
int clientPort = dp.getPort();
//输出
System.out.println("客户端IP:" + clientAddress.getHostAddress());
System.out.println("客户端端口号:" + clientPort);
System.out.println("客户端发送内容:" + new String(data,0,len));
//反馈到客户端
byte[] b = "OK".getBytes();
DatagramPacket sendDp = new DatagramPacket(b,b.length,clientAddress,clientPort);
//发送
ds.send(sendDp);
}catch(Exception e){
text-align: left; text-indent: 21pt; margin: 0cm 0cm 0pt 84pt
分享到:
相关推荐
有CSDN的MVB 陈跃峰老师摘写,适合JAVA初学者的一本书! 由本人收集整理成完成版转换成PDF格式上传CSDN! 作者:陈跃峰老师 收集整理:云低夕落人归
Java编程那些事儿,可以帮助开发人员在闲余的时间看看。
计算机软件开发的Java编程语言及应用——评《Java编程方法论》.pdf
JAVA编程那些事儿一书的完整版本,跟作者跟新同步,整理打包整合完成.
java网络编程——网络版题库程序(主要技术java+socket+多线程+mysql),程序是C/S 版本的,由于服务器端是java写的,所有客户端使用android也是很容易与服务器对接的
主要是用通俗的语言,解释清楚以下几个内容: 1、 程序设计是什么? 2、 Java语言相关基础语法及应用 3、 如何建立基础的程序逻辑以及其它编程和Java语言的相关问题
实训项目八:JAVA网络编程(csdn)————程序
我制作的java编程思想的教学课件,紧跟着“java编程思想教学材料——开端”
东西不错,和大家共享!原作者为陈跃峰,这里仅供学习交流用。
做坦克游戏,学Java编程(三)——实现GoodTank类.pdf
做坦克游戏,学Java编程(四)——添加炮弹类.pdf
java毕业设计——基于网络spider技术的网络新闻分析(论文+源代码+数据库+讲解视频).zip java毕业设计——基于网络spider技术的网络新闻分析(论文+源代码+数据库+讲解视频).zip java毕业设计——基于网络spider...
Java3D编程实践——网络上的三维动画.pdf
java8函数式编程(csdn)————程序
然后介绍了面向对象编程、JDK API结构、I/O技术、多线程技术、网络编程技术和界面开发技术等内容,并结合例子深入介绍了技术的实际应用,是一本实用的Java学习书籍。 本书难易适中,书中内容讲解和示例均源自作者...
做坦克游戏,学Java编程(一)——画出游戏窗口和坦克.pdf
做坦克游戏,学Java编程(二)——创建坦克类并实现BadTank.pdf
陈跃峰《Java编程那些事儿》,来自他的个人博客,不错的Java教程