Java 套接字通信中发送的确认不够快
我正在尝试为设备创建一个套接字侦听器,该设备在向服务器发送下一组数据之前需要确认。我可以发送确认信息,但在创建新连接时,我会丢失数据。我已将代码粘贴到下面Java 套接字通信中发送的确认不够快,java,sockets,Java,Sockets,我正在尝试为设备创建一个套接字侦听器,该设备在向服务器发送下一组数据之前需要确认。我可以发送确认信息,但在创建新连接时,我会丢失数据。我已将代码粘贴到下面 public void run() { try { servSoc = new ServerSocket(this.port); File file = new File("logs.txt"); // creates the file Socket server =
public void run() {
try {
servSoc = new ServerSocket(this.port);
File file = new File("logs.txt");
// creates the file
Socket server = null;
//FileWriter writer = new FileWriter(file);
while (true) {
try {
System.out.println("Waiting for client on port "
+ servSoc.getLocalPort() + "...");
server = servSoc.accept();
System.out.println("Just connected to "
+ server.getRemoteSocketAddress());
InputStreamReader in = new InputStreamReader(server.getInputStream());
//InputStreamReader in = new InputStreamReader(server.getInputStream());
DataOutputStream out =
new DataOutputStream(server.getOutputStream());
new Thread(new LogWriter(in, out)).start();
// Writes the content to the file
if (servSoc.isClosed()) {
System.out.println("Connection closed....");
servSoc.close();
}
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
s.printStackTrace();
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
} catch (IOException ex) {
java.util.logging.Logger.getLogger(SenselSocketListner.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
} finally {
}
}
public static void main(String args[]) {
int port = 8294;
Thread t = new SenselSocketListner(port);
t.start();
}
下面给出了我的日志编写器线程
public class LogWriter implements Runnable {
InputStreamReader in;
DataOutputStream out;
public LogWriter(InputStreamReader in, DataOutputStream out) {
this.in = in;
this.out = out;
}
@Override
public void run() {
try {
File file = new File("logs.txt");
// creates the file
if (!file.exists()) {
System.out.println("Creating File");
file.createNewFile();
}
String inputLine = null;
BufferedReader input = new BufferedReader(in);
System.out.println("Writing data....");
while ((inputLine = input.readLine()) != null) {
//System.out.println("Test");
System.out.println("Sending Acknowledgement....");
out.writeUTF("Upload successful");
out.writeUTF("Ok");
FileWriter fstream = new FileWriter(file, true);
BufferedWriter fbw = new BufferedWriter(fstream);
fbw.write(inputLine);
fbw.newLine();
fbw.flush();
fbw.close();
}
//DataOutputStream out =
//new DataOutputStream(server.getOutputStream());
//out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress() + "\nGoodbye!");
//server.close();
} catch (IOException ex) {
Logger.getLogger(LogWriter.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
}
}
与该设备有关的人士表示,我发送确认信息的速度可能不够快。请帮助我找到加快速度的方法,我注意到日志编写器中的“System.out.println(“Writing data….”);”语句后出现延迟。日志编写器中运行的while循环会将应用程序困在套接字关闭之前。如果您需要在套接字上进行会话,那么您必须知道将要发生什么——正如协议所定义的那样。如果是一行,就读一行。如果它是一个文本文件,您必须设计一个协议,通知您预期的字节数
此外,日志记录应在单个打开的日志文件上完成,每行之后不关闭。设备是否真正理解
writeUTF()的结果?除非它是用Java实现的,否则这是极不可能的。您当然应该直接写入消息的字节或字符
其他说明:
- 每行创建一个新的日志文件是在浪费时间。在读取循环之前打开文件,在循环之后关闭文件
- 如果服务器套接字已经关闭,则关闭它是没有意义的
- 当读取线程中的
readLine()
返回null时,应关闭接受的套接字
@laune此方法的契约明确规定将16位长度的字写入流,然后对实际字符进行修改的UTF编码。唯一可以读取此数据的方法是readUTF()
,它只在Java中找到,在硬件设备上是不需要的。这个问题一点也不奇怪,但是你对文档的高度选择性阅读有一点非常非常奇怪。@laune我建议你再看一次我的答案。除非该设备使用Java,否则它甚至不太可能实现readUTF()
,因此它也不太可能正确读取他用writeUTF()
编写的响应:这可以解释他的问题。这就是问题所在。例如,很有可能设备正在读线。你没有任何证据表明这不是问题的根源,在评估这个答案时,完全忽视read/writeUTF()
的独特性是有选择性的,也是非常奇怪的。我说,这种关于“设备”的说法让我困惑不已。通常的说法是“客户端软件”。我已经消除了我未能理解“设备”的所有痕迹。我从未想到有人可能无法以对称的方式实现协议,但所有其他奇怪的构造都应该提醒我。-你的“其他注释”与我之前写的内容一致。@laune因为他使用的是“设备”而不是“客户端软件”,所以很难看出你是怎么搞混的。我的一个“其他注释”也出现在你的帖子中。这是你的私人财产吗?版权?正在申请专利?请明确说明“设备”是否用Java编程,以及那边的阅读器是否使用readUTF。如果协议没有说明写入和读取字符串的具体方式,那将是一个糟糕的惊喜。正在使用的设备是第三方设备,因此我不知道它是否用java编程,正如EJP建议的那样。我尝试使用writechars而不是writeUTF,但它不起作用。我还尝试在收到输入流后立即将数据写入设备,但仍然没有成功。那么,是什么让您使用DataOutputStream呢?协议的定义是什么,即“第三方设备”真正期望的是什么?在发送一行数据后,它会这样做吗?就像DataOutputStream的例子一样,我刚刚在网上看到了一个示例代码,并使用它创建了我的套接字,我正在从那里构建其余的代码。设备希望“上传成功”和“确定”,并希望在收到每一行后收到。好吧,你不能假设为一个场景编写的代码适用于所有其他场景。如果设备需要几行文字,最好发送几行。