设计一个基于UDP的传输协议,能够实现丢包后重发,并使用java nio实现他. 这个怎么做?第一次做类似的题,求各位大神帮助下。代码最好了。。急急急。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 问题补充:1、为了UDP包不在IP层上被分片,所以设计UDP包每个不得大于以太网的MTU,综合考虑,包大小不超过512字节(不包括UDP头部)。2、使用java nio实现。3、设计一个应用层协议Head,使得支持重发,可以不考虑分片,即限制应用层协议数据包大小不会超过512字节即可。可参考TCP或者IP的重发机制。 如果是纯UDP协议,那就这样:* 消息头部包含一个序列号(sequence number),客户端检测该序列号来判断是否有丢包* 客户端检测到有丢包,那一定是收到了包p,以及包p+k,且k>1。那如何通知服务器端丢包呢?就只能发一个重传请求,而客户端同时应该开始队列从服务器端收到的包* 服务器收到了客户的重发请求,开始发送p+1到p+k-1的包* 客户端开始处理重发的包,如果在这中间仍然发现了丢包,那就继续发送重传请求,并队列发现丢包现象之后的重传包 > 注意这里的队列以及前面所说的是优先队列,按序列号排序,可以简化算法* 服务器端如果在完成重传之前又收到了重传请求,则应该队列该请求,在完成重传之后继续* 在客户端发送重传请求之后,如果服务器端没有在一定时间内回复,则判定该请求丢包,继续重传该请求UDP就是这么麻烦,慢慢享受吧 这是我在课余没事的时候写的一个东西,不知道是否正确,但基本上应该可以完成相应的功能。支持文件和文件夹的传输,不过这里的包大小为10000字节。我想改一下应该可以服务器package fileTransport;import java.io.BufferedInputStream;import java.io.File;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;import java.net.SocketTimeoutException;import java.net.UnknownHostException;public class SentFile { /** * @param args */ private InetAddress ip = null; private int port = 0; private DatagramSocket socket ; private InetAddress toIp = null; private int toPort = 0; public static void main(String[] args) throws UnknownHostException { SentFile s = new SentFile(InetAddress.getLocalHost(),11111); File file = new File("g:\\download"); s.sentFile(file); } public SentFile(InetAddress ip ,int port){ this.ip = ip ; this.port = port; try { socket = new DatagramSocket(port , ip); } catch (SocketException e) { e.printStackTrace(); } } public int sentFile(final File file){ Thread th = new Thread(){ public void run(){ byte[] b = new byte[1000]; DatagramPacket p = new DatagramPacket(b,b.length); try { socket.receive(p); byte[] date = p.getData(); System.out.println(new String(date)); } catch (IOException e) { e.printStackTrace(); } toIp = p.getAddress(); toPort = p.getPort(); send(file,""); byte[] over = "over".getBytes(); DatagramPacket p1 = new DatagramPacket(over,over.length); p1.setAddress(toIp); p1.setPort(toPort); try { socket.send(p1); } catch (IOException e) { e.printStackTrace(); } } }; th.start(); return 1; } private void send(File file,String name){ String name1 = name+"\\"+file.getName(); if(file.isDirectory()){ String s = "path"+name1; byte[] b = s.getBytes(); DatagramPacket p = new DatagramPacket(b,b.length); p.setAddress(toIp); p.setPort(toPort); try { socket.send(p); } catch (IOException e) { e.printStackTrace(); } try { System.out.println("recieve"); socket.receive(p); System.out.println("recieved"); } catch (IOException e) { e.printStackTrace(); } for(int i = 0 ; i<file.listFiles().length; i++){ send(file.listFiles()[i],name1); } } else{ String s = "file"+name1+"length"+file.length(); byte[] b = s.getBytes(); DatagramPacket p = new DatagramPacket(b,b.length); p.setAddress(toIp); p.setPort(toPort); try { socket.send(p); } catch (IOException e) { e.printStackTrace(); } try { socket.receive(p); } catch (IOException e) { e.printStackTrace(); } byte[] buffer = new byte[10000]; byte[] sendbuffer = new byte[10001]; DatagramPacket pk = new DatagramPacket(sendbuffer,10001); pk.setAddress(toIp); pk.setPort(toPort); long sum = 0; FileInputStream fis = null; BufferedInputStream bis = null; try { fis = new FileInputStream(file); bis = new BufferedInputStream(fis); bis.(10000); } catch (FileNotFoundException e) { e.printStackTrace(); } int read = 0; int num= 0; try { socket.setSoTimeout(3000); boolean re = false; while(-1!=(read=bis.read(buffer))){ sum+=read; System.arraycopy(buffer, 0, sendbuffer, 0, read); sendbuffer[10000] = Integer.valueOf(num).byteValue(); pk.setData(sendbuffer); socket.send(pk); System.out.println(sum); while(!re){ try{ socket.receive(p); re = true; }catch(SocketTimeoutException timeout){ socket.send(pk); } } re = false; Integer bn = new Integer(p.getData()[0]); System.out.println(bn+","+num+","+read); if(bn==-1){ break; } if(bn!=(num+1)%100){ bis.reset(); } else{ bis.(10000); num++; num%=100; } } } catch (IOException e) { e.printStackTrace(); } try { bis.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } } }} 客户端:package fileTransport;import java.awt.FileDialog;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FilenameFilter;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.SocketException;import java.net.UnknownHostException;import java.util.ArrayList;import javax.swing.JButton;import javax.swing.JFileChooser;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.UIManager;public class GetFile { /** * @param args * @throws UnknownHostException */ public static void main(String[] args) throws UnknownHostException { GetFile g; try { g = new GetFile(InetAddress.getLocalHost(),11111,"download"); g.getFile(); } catch (UnknownHostException e1) { e1.printStackTrace(); } } private DatagramSocket socket = null; private String name=""; private InetAddress ip = null; private int port = 0 ; private String saveName=null; public GetFile(InetAddress ip ,int port,String name){ this.ip = ip ; this.port = port ; this.name = name; try { this.socket = new DatagramSocket(); } catch (SocketException e) { e.printStackTrace(); } } public String chooseSavePath(){ try { if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1){ UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } } catch (Exception e1) { System.out.println("设置界面感官异常!"); e1.printStackTrace(); } JFileChooser fileChooser = new JFileChooser(); fileChooser.setDialogType(JFileChooser.SAVE_DIALOG); fileChooser.setSelectedFile(new File(name)); int i = fileChooser.showSaveDialog(null); System.out.println(i); if(i == JFileChooser.APPROVE_OPTION){ if(fileChooser.getSelectedFile().exists()){ JOptionPane.showConfirmDialog(null, "文件已存在,请重新命名"); return chooseSavePath(); } return fileChooser.getSelectedFile().getAbsolutePath(); } return null; } public void getFile(){ String path = chooseSavePath(); System.out.println(path); if(path!=null){ byte[] b = "ok".getBytes(); DatagramPacket p = new DatagramPacket(b,b.length); p.setPort(port); p.setAddress(ip); try { socket.send(p); } catch (IOException e) { e.printStackTrace(); } boolean end = false; while(!end){ byte[] data = new byte[1024]; DatagramPacket p1 = new DatagramPacket(data,data.length); try { socket.receive(p1); } catch (IOException e) { e.printStackTrace(); } String msg = new String(p1.getData()).trim(); System.out.println(msg); if(msg.equals("over")){ end = true; System.out.println(end); } else{ String type = msg.substring(0, 4); String newName = path+msg.substring(msg.indexOf(name)+name.length()); if(type.equals("path")){ File fpath = new File(newName); if(fpath.exists()){ JOptionPane jop = new JOptionPane(); JButton[] options = new JButton[3]; options[0]= new JButton("覆盖"); options[1] = new JButton("保存为:"+this.saveName+"(new)"); options[2] = new JButton("取消"); jop.setOptions(options); jop.setVisible(true); } else{ fpath.mkdirs(); } byte[] reb = "path".getBytes(); DatagramPacket respons = new DatagramPacket(reb,reb.length); respons.setAddress(ip); respons.setPort(port); try { socket.send(respons); } catch (IOException e) { e.printStackTrace(); } } else if(type.equals("file")){ File file = new File(newName.substring(0, newName.indexOf("length"))); FileOutputStream fos = null; try { fos = new FileOutputStream(file); } catch (FileNotFoundException e1) { e1.printStackTrace(); } byte[] reb = "file".getBytes(); DatagramPacket respons = new DatagramPacket(reb,reb.length); respons.setAddress(ip); respons.setPort(port); try { socket.send(respons); } catch (IOException e) { e.printStackTrace(); } String s1=newName.replaceAll(".*[^\\d](?=(\\d+))",""); long size = Long.valueOf(s1); long sum = 0; byte[] buffer = new byte[10001]; DatagramPacket pk = new DatagramPacket(buffer,10001); int k = 0 ; byte[] bn = new byte[1]; for(long j = 0 ; j<size/10000 ; j++){ try { sum+=10000; socket.receive(pk); Integer num = new Integer(buffer[10000]); if(num==k){ fos.write(buffer, 0, 10000); fos.flush(); if(j!=size/10000-1){ k++; k%=100; bn[0] = Integer.valueOf(k).byteValue(); System.out.println(bn[0]); respons.setData(bn); socket.send(respons); } else{ if(size%10000==0){ bn[0] = Integer.valueOf(-1).byteValue(); System.out.println(bn[0]); respons.setData(bn); socket.send(respons); } } } else{ bn[0] = Integer.valueOf(k).byteValue(); System.out.println(bn[0]); respons.setData(bn); socket.send(respons); j--; } } catch (IOException e) { e.printStackTrace(); } } if(size%10000!=0){ if(size>10000){ k++; k%=100; bn[0] = Integer.valueOf(k).byteValue(); System.out.println(bn[0]); respons.setData(bn); try { socket.send(respons); } catch (IOException e1) { e1.printStackTrace(); } } try { socket.receive(pk); bn[0] = Integer.valueOf(-1).byteValue(); respons.setData(bn); socket.send(respons); } catch (IOException e) { e.printStackTrace(); } try { fos.write(buffer, 0, (int)(size%10000)); fos.flush(); } catch (IOException e) { e.printStackTrace(); } } try { fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } else{ System.out.println("文件传输失败"); socket.close(); System.exit(0); } } } } else{ return; } }} 这个代码不是我要的,你用的是io,我需要的nio写的!!! 既然如此。。给你一个简易的开头吧。。下面的代码每隔一秒发送一个int到ChannelReader类,由它打印出。至于buffer为什么要这么多操作,仔细看API文档吧import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.DatagramChannel;public class UDPDemo { public static void main(final String[] s) throws IOException, InterruptedException { new Thread(new ChannelReader()).start(); DatagramChannel channel = DatagramChannel.open(); channel.connect(new InetSocketAddress("localhost", 9999)); ByteBuffer buffer = ByteBuffer.allocate(50); int i = 0; while (true) { buffer.putInt(i++); buffer.flip(); channel.write(buffer); buffer.clear(); Thread.sleep(1000); } } private static class ChannelReader implements Runnable { @Override public void run() { try { DatagramChannel channel = DatagramChannel.open(); channel.bind(new InetSocketAddress("localhost", 9999)); ByteBuffer buffer = ByteBuffer.allocate(50); while (true) { channel.receive(buffer); System.out.println(buffer.getInt(0)); buffer.clear(); } } catch (IOException e) { e.printStackTrace(); } } }} 我弄明白了你的这个demo,bufer的这些操作也明白了,先谢谢你。另外,我想问的是设计一个UDP传输协议,这个怎么体现出来? 传输协议要你自己设计。所谓协议就是客户端和服务器端都认同的消息格式。UDPDemo中包含了一个简易协议,那就是每个包开头都是一个int所以你如果要实现更复杂的功能,就要定义更复杂的协议在我这个例子里,每个包开头的int是逐个递增的。如果你想检测到丢包,那就在客户端写一个逻辑,来判断收到的这个包的这个int,是不是之前那个包的int值+1至于重发,也就是你检测到丢包的时候,客户端要告诉服务器它丢包了,也是通过发送一个UDP包到服务器,然后服务器收到这个包之后开始回传丢失的那些包。代码其实可以从这个Demo改,只不过现在客户端和服务器端都要包含一个Reader一个Sender了 不是。协议是一种约定,让接受方能正确解码发送方的数据。当你面对一堆字节的时候,怎样把它还原成原来的消息,这就是协议规定的内容。比如说,前四个字节是一个int java rmi编程 异常(各位高手请进) 请问谁有javax.media包 jni的内存泄漏问题 关于socket传输文件 JDK1.5以前的JDK版本里有什么方法可以利用给定的父类的实例对象和子类的类名将父类强制转换为子类实例啊(反射方面的)? 请各位高手进来看看 关于JAVA中多维数组的使用! java中怎样向文件中写入汉字 java如何实现类似于Delphi中的DBGrid控件的功能? 回答我的问题呀!拜托了! eclipse启动报错如何解决 Telnet获取多个服务器的数据,中间总是停止!求高手解决!
1、为了UDP包不在IP层上被分片,所以设计UDP包每个不得大于以太网的MTU,综合考虑,包大小不超过512字节(不包括UDP头部)。2、使用java nio实现。3、设计一个应用层协议Head,使得支持重发,可以不考虑分片,即限制应用层协议数据包大小不会超过512字节即可。可参考TCP或者IP的重发机制。
* 消息头部包含一个序列号(sequence number),客户端检测该序列号来判断是否有丢包
* 客户端检测到有丢包,那一定是收到了包p,以及包p+k,且k>1。那如何通知服务器端丢包呢?就只能发一个重传请求,而客户端同时应该开始队列从服务器端收到的包
* 服务器收到了客户的重发请求,开始发送p+1到p+k-1的包
* 客户端开始处理重发的包,如果在这中间仍然发现了丢包,那就继续发送重传请求,并队列发现丢包现象之后的重传包
> 注意这里的队列以及前面所说的是优先队列,按序列号排序,可以简化算法
* 服务器端如果在完成重传之前又收到了重传请求,则应该队列该请求,在完成重传之后继续
* 在客户端发送重传请求之后,如果服务器端没有在一定时间内回复,则判定该请求丢包,继续重传该请求UDP就是这么麻烦,慢慢享受吧
服务器package fileTransport;import java.io.BufferedInputStream;
import java.io.File;
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;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;public class SentFile { /**
* @param args
*/
private InetAddress ip = null;
private int port = 0;
private DatagramSocket socket ;
private InetAddress toIp = null;
private int toPort = 0;
public static void main(String[] args) throws UnknownHostException {
SentFile s = new SentFile(InetAddress.getLocalHost(),11111);
File file = new File("g:\\download");
s.sentFile(file);
}
public SentFile(InetAddress ip ,int port){
this.ip = ip ;
this.port = port;
try {
socket = new DatagramSocket(port , ip);
} catch (SocketException e) {
e.printStackTrace();
}
}
public int sentFile(final File file){
Thread th = new Thread(){
public void run(){
byte[] b = new byte[1000];
DatagramPacket p = new DatagramPacket(b,b.length);
try {
socket.receive(p);
byte[] date = p.getData();
System.out.println(new String(date));
} catch (IOException e) {
e.printStackTrace();
}
toIp = p.getAddress();
toPort = p.getPort();
send(file,"");
byte[] over = "over".getBytes();
DatagramPacket p1 = new DatagramPacket(over,over.length);
p1.setAddress(toIp);
p1.setPort(toPort);
try {
socket.send(p1);
} catch (IOException e) {
e.printStackTrace();
}
}
};
th.start();
return 1;
}
private void send(File file,String name){
String name1 = name+"\\"+file.getName();
if(file.isDirectory()){
String s = "path"+name1;
byte[] b = s.getBytes();
DatagramPacket p = new DatagramPacket(b,b.length);
p.setAddress(toIp);
p.setPort(toPort);
try {
socket.send(p);
} catch (IOException e) {
e.printStackTrace();
}
try {
System.out.println("recieve");
socket.receive(p);
System.out.println("recieved");
} catch (IOException e) {
e.printStackTrace();
}
for(int i = 0 ; i<file.listFiles().length; i++){
send(file.listFiles()[i],name1);
}
}
else{
String s = "file"+name1+"length"+file.length();
byte[] b = s.getBytes();
DatagramPacket p = new DatagramPacket(b,b.length);
p.setAddress(toIp);
p.setPort(toPort);
try {
socket.send(p);
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.receive(p);
} catch (IOException e) {
e.printStackTrace();
}
byte[] buffer = new byte[10000];
byte[] sendbuffer = new byte[10001];
DatagramPacket pk = new DatagramPacket(sendbuffer,10001);
pk.setAddress(toIp);
pk.setPort(toPort);
long sum = 0;
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
bis.(10000);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int read = 0;
int num= 0;
try {
socket.setSoTimeout(3000);
boolean re = false;
while(-1!=(read=bis.read(buffer))){
sum+=read;
System.arraycopy(buffer, 0, sendbuffer, 0, read);
sendbuffer[10000] = Integer.valueOf(num).byteValue();
pk.setData(sendbuffer);
socket.send(pk);
System.out.println(sum);
while(!re){
try{
socket.receive(p);
re = true;
}catch(SocketTimeoutException timeout){
socket.send(pk);
}
}
re = false;
Integer bn = new Integer(p.getData()[0]);
System.out.println(bn+","+num+","+read);
if(bn==-1){
break;
}
if(bn!=(num+1)%100){
bis.reset();
}
else{
bis.(10000);
num++;
num%=100;
}
}
} catch (IOException e) {
e.printStackTrace();
}
try {
bis.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package fileTransport;import java.awt.FileDialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;public class GetFile { /**
* @param args
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException {
GetFile g;
try {
g = new GetFile(InetAddress.getLocalHost(),11111,"download");
g.getFile();
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
}
private DatagramSocket socket = null;
private String name="";
private InetAddress ip = null;
private int port = 0 ;
private String saveName=null;
public GetFile(InetAddress ip ,int port,String name){
this.ip = ip ;
this.port = port ;
this.name = name;
try {
this.socket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
}
}
public String chooseSavePath(){
try {
if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1){
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
}
} catch (Exception e1) {
System.out.println("设置界面感官异常!");
e1.printStackTrace();
}
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
fileChooser.setSelectedFile(new File(name));
int i = fileChooser.showSaveDialog(null);
System.out.println(i);
if(i == JFileChooser.APPROVE_OPTION){
if(fileChooser.getSelectedFile().exists()){
JOptionPane.showConfirmDialog(null, "文件已存在,请重新命名");
return chooseSavePath();
}
return fileChooser.getSelectedFile().getAbsolutePath();
}
return null;
}
public void getFile(){
String path = chooseSavePath();
System.out.println(path);
if(path!=null){
byte[] b = "ok".getBytes();
DatagramPacket p = new DatagramPacket(b,b.length);
p.setPort(port);
p.setAddress(ip);
try {
socket.send(p);
} catch (IOException e) {
e.printStackTrace();
}
boolean end = false;
while(!end){
byte[] data = new byte[1024];
DatagramPacket p1 = new DatagramPacket(data,data.length);
try {
socket.receive(p1);
} catch (IOException e) {
e.printStackTrace();
}
String msg = new String(p1.getData()).trim();
System.out.println(msg);
if(msg.equals("over")){
end = true;
System.out.println(end);
}
else{
String type = msg.substring(0, 4);
String newName = path+msg.substring(msg.indexOf(name)+name.length());
if(type.equals("path")){
File fpath = new File(newName);
if(fpath.exists()){
JOptionPane jop = new JOptionPane();
JButton[] options = new JButton[3];
options[0]= new JButton("覆盖");
options[1] = new JButton("保存为:"+this.saveName+"(new)");
options[2] = new JButton("取消");
jop.setOptions(options);
jop.setVisible(true);
}
else{
fpath.mkdirs();
}
byte[] reb = "path".getBytes();
DatagramPacket respons = new DatagramPacket(reb,reb.length);
respons.setAddress(ip);
respons.setPort(port);
try {
socket.send(respons);
} catch (IOException e) {
e.printStackTrace();
}
}
else if(type.equals("file")){
File file = new File(newName.substring(0, newName.indexOf("length")));
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
byte[] reb = "file".getBytes();
DatagramPacket respons = new DatagramPacket(reb,reb.length);
respons.setAddress(ip);
respons.setPort(port);
try {
socket.send(respons);
} catch (IOException e) {
e.printStackTrace();
}
String s1=newName.replaceAll(".*[^\\d](?=(\\d+))","");
long size = Long.valueOf(s1);
long sum = 0;
byte[] buffer = new byte[10001];
DatagramPacket pk = new DatagramPacket(buffer,10001);
int k = 0 ;
byte[] bn = new byte[1];
for(long j = 0 ; j<size/10000 ; j++){
try {
sum+=10000;
socket.receive(pk);
Integer num = new Integer(buffer[10000]);
if(num==k){
fos.write(buffer, 0, 10000);
fos.flush();
if(j!=size/10000-1){
k++;
k%=100;
bn[0] = Integer.valueOf(k).byteValue();
System.out.println(bn[0]);
respons.setData(bn);
socket.send(respons);
}
else{
if(size%10000==0){
bn[0] = Integer.valueOf(-1).byteValue();
System.out.println(bn[0]);
respons.setData(bn);
socket.send(respons);
}
}
}
else{
bn[0] = Integer.valueOf(k).byteValue();
System.out.println(bn[0]);
respons.setData(bn);
socket.send(respons);
j--;
}
} catch (IOException e) {
e.printStackTrace();
}
}
if(size%10000!=0){
if(size>10000){
k++;
k%=100;
bn[0] = Integer.valueOf(k).byteValue();
System.out.println(bn[0]);
respons.setData(bn);
try {
socket.send(respons);
} catch (IOException e1) {
e1.printStackTrace();
}
}
try {
socket.receive(pk);
bn[0] = Integer.valueOf(-1).byteValue();
respons.setData(bn);
socket.send(respons);
} catch (IOException e) {
e.printStackTrace();
}
try {
fos.write(buffer, 0, (int)(size%10000));
fos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
else{
System.out.println("文件传输失败");
socket.close();
System.exit(0);
}
}
}
}
else{
return;
}
}
}
下面的代码每隔一秒发送一个int到ChannelReader类,由它打印出。至于buffer为什么要这么多操作,仔细看API文档吧
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;public class UDPDemo {
public static void main(final String[] s) throws IOException, InterruptedException { new Thread(new ChannelReader()).start(); DatagramChannel channel = DatagramChannel.open();
channel.connect(new InetSocketAddress("localhost", 9999)); ByteBuffer buffer = ByteBuffer.allocate(50);
int i = 0;
while (true) {
buffer.putInt(i++);
buffer.flip();
channel.write(buffer);
buffer.clear();
Thread.sleep(1000);
}
} private static class ChannelReader implements Runnable {
@Override
public void run() {
try {
DatagramChannel channel = DatagramChannel.open();
channel.bind(new InetSocketAddress("localhost", 9999));
ByteBuffer buffer = ByteBuffer.allocate(50);
while (true) {
channel.receive(buffer);
System.out.println(buffer.getInt(0));
buffer.clear();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
UDPDemo中包含了一个简易协议,那就是每个包开头都是一个int
所以你如果要实现更复杂的功能,就要定义更复杂的协议在我这个例子里,每个包开头的int是逐个递增的。如果你想检测到丢包,那就在客户端写一个逻辑,来判断收到的这个包的这个int,是不是之前那个包的int值+1至于重发,也就是你检测到丢包的时候,客户端要告诉服务器它丢包了,也是通过发送一个UDP包到服务器,然后服务器收到这个包之后开始回传丢失的那些包。代码其实可以从这个Demo改,只不过现在客户端和服务器端都要包含一个Reader一个Sender了