客户端和服务器通信编程。客户端需求:把一个图片文件发送到服务端并读取回馈信息。 服务端需求:接收客户端发送
过来的图片数据。进行存储后,回馈一个“上传成功”字样。
接收端:
package ch05;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class udpRecieverTest {
public static void main(String[] args) {
System.out.println("=====接收端=====");
try {
DatagramSocket ds = new DatagramSocket(8889);
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b, b.length);
ds.receive(dp);
System.out.println("接收到数据:" + new String(b,0,b.length));
String str = "Hello,this is lisi!";
DatagramPacket dpsend = new DatagramPacket(str.getBytes(),str.length(),dp.getAddress(),dp.getPort());
ds.send(dpsend);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这段代码实现了一个简单的UDP接收端程序,用于接收来自发送端的数据,并进行一些基本的数据交互。下面是代码的解析:
-
导入了
java.io.IOException
和java.net
相关的类,用于处理输入输出和网络通信。 -
创建了一个名为
udpRecieverTest
的公共类。 -
在
main
方法中,打印出 "=====接收端=====",用于显示接收端开始运行。 -
在
try
块中,创建了一个DatagramSocket
实例ds
,通过指定端口号 8889 来创建一个接收端的套接字。 -
创建一个字节数组
b
,用于存储接收到的数据。 -
创建一个
DatagramPacket
实例dp
,用于接收数据包。该数据包使用之前创建的字节数组b
。 -
使用
ds.receive(dp)
方法接收来自发送端的数据。当接收到数据包后,数据将被存储在字节数组b
中。 -
使用
new String(b, 0, b.length)
将字节数组中的数据转换为字符串,并打印出来。 -
创建一个字符串
str
,用于构造要发送的数据。 -
创建一个新的
DatagramPacket
实例dpsend
,用于构造要发送的数据包。这里使用str.getBytes()
将字符串转换为字节数组,然后指定目标的 IP 地址和端口号为之前接收到的数据包的地址和端口。 -
使用
ds.send(dpsend)
发送数据包。 -
在
catch
块中捕获SocketException
和IOException
异常,并打印异常信息。
总体来说,这段代码创建了一个 UDP 接收端,监听指定的端口(8889),接收发送端发送的数据,然后将收到的数据进行简单的处理并发送回去。注意,UDP 是一种面向无连接的协议,因此没有建立连接的过程,数据包可以直接发送和接收。
发送端:
package ch05;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class udpClientTest {
public static void main(String[] args) {
System.out.println("=====客户端-发送图片=====");
udpSdenderThread us = new udpSdenderThread(8889, "send.jpg");
new Thread(us).start();
}
}
class udpSdenderThread implements Runnable{
private String filename;
private byte[] buffer;
private int port;
public udpSdenderThread(int port,String filename) {
super();
this.port = port;
this.filename = filename;
this.buffer = new byte[1024];
}
public void run() {
try {
DatagramSocket ds = new DatagramSocket();
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(filename));
int count = 0;
count = bin.read(buffer,0,1024);
while(count > 0){
DatagramPacket dp =new DatagramPacket(buffer,0,count,
InetAddress.getByName("127.0.0.1"),port);
ds.send(dp);
System.out.println("sended!");
Thread.sleep(1000);
count = bin.read(buffer,0,1024);
}
System.out.println("send finished!");
bin.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这段代码实现了一个UDP客户端程序,用于发送图片数据。下面是代码的解析:
-
在
udpClientTest
类的main
方法中,打印出 "=====客户端-发送图片=====",用于显示客户端开始运行。 -
创建一个名为
udpSdenderThread
的类,实现了Runnable
接口,用于发送图片数据的线程类。 -
在
udpSdenderThread
类中,定义了成员变量filename
(图片文件名)、buffer
(用于存储图片数据的字节数组)、port
(目标端口号)。 -
构造方法接收传入的端口号和图片文件名,并初始化成员变量。
-
实现了
run
方法,该方法将会在新的线程中运行。 -
在
run
方法中,创建一个DatagramSocket
实例ds
,用于发送数据包。 -
使用
BufferedInputStream
读取图片文件,每次读取最多 1024 字节的数据到buffer
数组中。 -
进入循环,当成功读取到数据时(
count
大于 0),创建一个DatagramPacket
实例dp
,将buffer
数组中的数据封装为数据包。 -
使用
InetAddress.getByName("127.0.0.1")
获取目标 IP 地址(这里指本地地址),并指定端口号为之前传入的端口号。 -
使用
ds.send(dp)
发送数据包。 -
打印 "sended!",表示数据包已发送。
-
使用
Thread.sleep(1000)
睡眠 1 秒,然后继续读取下一批数据。 -
重复步骤 8~12,直到无法读取更多数据,此时
count
为 -1,退出循环。 -
打印 "send finished!",表示发送完成。
-
关闭
BufferedInputStream
,释放资源。 -
在各个异常块中捕获
SocketException
、FileNotFoundException
、IOException
和InterruptedException
异常,并打印异常信息。
总体来说,这段代码创建了一个 UDP 客户端,用于发送指定图片文件的数据。该客户端通过循环读取图片文件数据并封装成数据包发送给指定的 IP 地址和端口。注意,这里使用了多线程来发送数据,以避免阻塞主线程。