[英]How to encapsulate a SCTP packet in UDP and send it over UDP channel in java
我必须使用 SCTP 协议传输文件。 我已经在 java 中编写了代码,但是当我使用 4G hotspot.network 时代码不起作用。 所以我遇到了这个 RFC,它讨论了 SCTP 的 UDP 封装。 我想知道是否有一个实现可以用来将 SCTP 数据包封装在 UDP 中并通过 UDP 通道发送它,以便它可以大量遍历 NATted.network。 我目前发送数据包的代码如下:
import java.io.*;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.*;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpServerChannel;
public class Main {
SctpChannel connectionChannelPrimary;
SctpChannel connectionChannelSecondary;
InetSocketAddress serverSocketAddressPrimary;
InetSocketAddress serverSocketAddressSecondary;
String directoryPath;
public Main() {
serverSocketAddressPrimary = new InetSocketAddress(6002);
serverSocketAddressSecondary = new InetSocketAddress(6003);
}
public void setDirectoryPath(String directoryPath) {
this.directoryPath = directoryPath;
}
public String getDirectoryPath() {
return directoryPath;
}
public void establishConnection(int connId) throws IOException {
SctpServerChannel sctpServerChannel = SctpServerChannel.open();
if (connId == 0) {
sctpServerChannel.bind(serverSocketAddressPrimary);
connectionChannelPrimary = sctpServerChannel.accept();
System.out.println("connection established for primary");
} else {
sctpServerChannel.bind(serverSocketAddressSecondary);
connectionChannelSecondary = sctpServerChannel.accept();
System.out.println("connection established for helper");
}
}
ArrayList<String> getAllFiles() {
File directory = new File(this.directoryPath);
ArrayList<String> fileNames = new ArrayList<>();
for (File fileEntry : Objects.requireNonNull(directory.listFiles())) {
if (fileEntry.isFile()) {
fileNames.add(fileEntry.getName());
}
}
Collections.sort(fileNames);
return fileNames;
}
public byte[] readFile(String filename) throws IOException {
String extraString = "\n\n\n\nNRL\n\n\n";
File file = new File(filename);
FileInputStream fl = new FileInputStream(file);
ByteBuffer finalBuffer = ByteBuffer.allocate((int) (file.length() + extraString.length()));
byte[] arr = new byte[(int) file.length()];
int res = fl.read(arr);
if (res < 0) {
System.out.println("Error in reading file");
fl.close();
return null;
}
fl.close();
finalBuffer.put(arr);
finalBuffer.put(extraString.getBytes());
byte[] tmp = new byte[extraString.length()];
finalBuffer.position((int) (file.length() - 1));
finalBuffer.get(tmp, 0, tmp.length);
return finalBuffer.array();
}
public void sendBytes(String filename, int connId) throws IOException {
byte[] message = readFile(filename);
assert message != null;
System.out.println(message.length);
int tmp = 0;
int cntIndex = 60000;
int prevIndex = 0;
boolean isBreak = false;
while (!isBreak) {
byte[] slice;
if (prevIndex + 60000 >= message.length) {
slice = Arrays.copyOfRange(message, prevIndex, message.length);
isBreak = true;
} else {
slice = Arrays.copyOfRange(message, prevIndex, cntIndex);
prevIndex = cntIndex;
cntIndex = cntIndex + 60000;
}
final ByteBuffer byteBuffer = ByteBuffer.allocate(64000);
final MessageInfo messageInfo = MessageInfo.createOutgoing(null, 0);
byteBuffer.put(slice);
byteBuffer.flip();
tmp += slice.length;
try {
if (connId == 0) connectionChannelPrimary.send(byteBuffer, messageInfo);
else connectionChannelSecondary.send(byteBuffer, messageInfo);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(tmp);
}
public static void main(String[] args) throws IOException {
String bgFilePath = "/home/iiitd/Desktop/background/";
String fgFilePath = "/home/iiitd/Desktop/foreground/";
Main myObj = new Main();
myObj.setDirectoryPath("/home/iiitd/Desktop/tmp/");
myObj.establishConnection(1);
myObj.establishConnection(0);
ArrayList<String> files = myObj.getAllFiles();
for (String tmpFile : files) {
String cntFilePath = myObj.getDirectoryPath() + tmpFile;
myObj.sendBytes(cntFilePath,0);
}
}
}
RFC 链接: https://datatracker.ietf.org/doc/html/draft-ietf-tsvwg-sctp-udp-encaps-09
在 C 中,我认为usrsctp是 UDP 上 SCTP 的一个流行实现。如果我理解正确的话,它曾被谷歌浏览器使用过(尽管我看到他们提到在某些时候转向“dcsctp”)。 我也在 2016 年的 Firefox 来源的镜像中看到了它,不知道今天的 state 是什么。
因此,一种解决方案是使用 JNI 包装usrsctp
。 看起来这正是jitsi-sctp正在做的事情。 我没用过,但我想看看。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.