我想通过Socket发送多个随机值。我认为数组是发送它们的最佳方式。但是我不知道如何将数组写入Socket outputStream?
我的java类
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.io.*;
import java.util.Random;
class NodeCommunicator {
public static void main(String[] args) {
try {
Socket nodejs = new Socket("localhost", 8181);
Random randomGenerator = new Random();
for (int idx = 1; idx <= 1000; ++idx){
Thread.sleep(500);
int randomInt = randomGenerator.nextInt(35);
sendMessage(nodejs, randomInt + " ");
System.out.println(randomInt);
}
while(true){
Thread.sleep(1000);
}
} catch (Exception e) {
System.out.println("Connection terminated..Closing Java Client");
System.out.println("Error :- "+e);
}
}
public static void sendMessage(Socket s, String message) throws IOException {
s.getOutputStream().write(message.getBytes("UTF-8"));
s.getOutputStream().flush();
}
}
答案 0 :(得分:8)
使用java.io.DataOutputStream / DataInputStream对,他们知道如何读取整数。将信息作为长度+随机数的数据包发送。
发送方
Socket sock = new Socket("localhost", 8181);
DataOutputStream out = new DataOutputStream(sock.getOutputStream());
out.writeInt(len);
for(int i = 0; i < len; i++) {
out.writeInt(randomGenerator.nextInt(35))
...
接收器
DataInputStream in = new DataInputStream(sock.getInputStream());
int len = in.readInt();
for(int i = 0; i < len; i++) {
int next = in.readInt();
...
答案 1 :(得分:3)
Java数组实际上是Object
,而且它们实现了Serializable
接口。因此,您可以序列化您的数组,获取字节并通过套接字发送它们。这应该这样做:
public static void sendMessage(Socket s, int[] myMessageArray)
throws IOException {
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bs);
os.writeObject(myMessageArray);
byte[] messageArrayBytes = bs.toByteArray();
s.getOutputStream().write(messageArrayBytes);
s.getOutputStream().flush();
}
这真的很简洁,它不仅适用于int[]
,也适用于任何Serializable
对象。
修改强> 再考虑一下,这更简单:
发送方:
public static void sendMessage(Socket s, int[] myMessageArray)
throws IOException {
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(myMessageArray);
}
接收器:
public static int[] getMessage(Socket s)
throws IOException {
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
int[] myMessageArray = (int[])ois.readObject();
return myMessageArray;
}
我将离开我的第一个答案(因为它也有效),它对于将对象写入UDP DatagramSockets
和DatagramPackets
没有任何流非常有用。
答案 2 :(得分:2)
我建议简单地使用一些分隔符连接字符串中的int
值,例如: @@
,然后立即传输最终的连接字符串。在接收方,只需使用相同的分隔符拆分字符串以获取int[]
,例如:
Random randomGenerator = new Random();
StringBuilder numToSend = new StringBuilder("");
numToSend.append(randomGenerator.nextInt(35));
for (int idx = 2; idx <= 1000; ++idx){
Thread.sleep(500);
numToSend.append("@@").append(randomGenerator.nextInt(35));
}
String numsString = numToSend.toString();
System.out.println(numsString);
sendMessage(nodejs, numsString);
在接收方,获取您的字符串并拆分为:
Socket remotejs = new Socket("remotehost", 8181);
BufferedReader in = new BufferedReader(
new InputStreamReader(remotejs.getInputStream()));
String receivedNumString = in.readLine();
String[] numstrings = receivedNumString.split("@@");
int[] nums = new int[numstrings.length];
int indx = 0;
for(String numStr: numstrings){
nums[indx++] = Integer.parseInt(numStr);
}
答案 3 :(得分:1)
嗯,流是一个字节流,因此您必须将数据编码为一个字节序列,并在接收端对其进行解码。如何编写数据取决于您希望如何编码它。
0到34之间的数字适合单个字节,这可以很简单:
outputStream.write(randomNumber);
另一方面:
int randomNumber = inputStream.read();
当然,在每个字节之后刷新流不是很有效(因为它将为每个字节生成一个网络数据包,并且每个网络数据包包含几十个字节的头和路由信息......)。如果性能很重要,你可能也想要使用BufferedOutputStream。
答案 4 :(得分:1)
因此,您可以比较我编写的模板的替代格式,该模板允许您使用您希望的任何格式,或比较替代方案。
abstract class DataSocket implements Closeable {
private final Socket socket;
protected final DataOutputStream out;
protected final DataInputStream in;
DataSocket(Socket socket) throws IOException {
this.socket = socket;
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}
public void writeInts(int[] ints) throws IOException {
writeInt(ints.length);
for (int i : ints)
writeInt(i);
endOfBlock();
}
protected abstract void writeInt(int i) throws IOException;
protected abstract void endOfBlock() throws IOException;
public int[] readInts() throws IOException {
nextBlock();
int len = readInt();
int[] ret = new int[len];
for (int i = 0; i < len; i++)
ret[i] = readInt();
return ret;
}
protected abstract void nextBlock() throws IOException;
protected abstract int readInt() throws IOException;
public void close() throws IOException {
out.close();
in.close();
socket.close();
}
}
二进制格式,4字节整数
class BinaryDataSocket extends DataSocket {
BinaryDataSocket(Socket socket) throws IOException {
super(socket);
}
@Override
protected void writeInt(int i) throws IOException {
out.writeInt(i);
}
@Override
protected void endOfBlock() throws IOException {
out.flush();
}
@Override
protected void nextBlock() {
// nothing
}
@Override
protected int readInt() throws IOException {
return in.readInt();
}
}
停止位编码二进制,每7位一个字节。
class CompactBinaryDataSocket extends DataSocket {
CompactBinaryDataSocket(Socket socket) throws IOException {
super(socket);
}
@Override
protected void writeInt(int i) throws IOException {
// uses one byte per 7 bit set.
long l = i & 0xFFFFFFFFL;
while (l >= 0x80) {
out.write((int) (l | 0x80));
l >>>= 7;
}
out.write((int) l);
}
@Override
protected void endOfBlock() throws IOException {
out.flush();
}
@Override
protected void nextBlock() {
// nothing
}
@Override
protected int readInt() throws IOException {
long l = 0;
int b, count = 0;
while ((b = in.read()) >= 0x80) {
l |= (b & 0x7f) << 7 * count++;
}
if (b < 0) throw new EOFException();
l |= b << 7 * count;
return (int) l;
}
}
最后用新行编码的文本。
class TextDataSocket extends DataSocket {
TextDataSocket(Socket socket) throws IOException {
super(socket);
}
private boolean outBlock = false;
@Override
protected void writeInt(int i) throws IOException {
if (outBlock) out.write(' ');
out.write(Integer.toString(i).getBytes());
outBlock = true;
}
@Override
protected void endOfBlock() throws IOException {
out.write('\n');
out.flush();
outBlock = false;
}
private Scanner inLine = null;
@Override
protected void nextBlock() throws IOException {
inLine = new Scanner(in.readLine());
}
@Override
protected int readInt() throws IOException {
return inLine.nextInt();
}
}
答案 5 :(得分:0)
如果要向套接字发送多个随机值,请选择一种简单格式并让双方同意(发送方和接收方),例如您只需选择;
之类的分隔符并创建包含该分隔符的所有值的字符串,然后发送
答案 6 :(得分:0)
Android Socket SERVER Example以接收整数数组而不是字符串:
...
class CommunicationThread implements Runnable {
private ObjectInputStream input;
public CommunicationThread(Socket clientSocket) {
try {
this.input = new ObjectInputStream(clientSocket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
int[] myMessageArray = (int[]) input.readObject();
String read = null;
read = String.format("%05X", myMessageArray[0] & 0x0FFFFF);
int i = 1;
do {
read = read + ", " + String.format("%05X", myMessageArray[i] & 0x0FFFFF);
i++;
} while (i < myMessageArray.length);
read = read + " (" + myMessageArray.length + " bytes)";
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
...