Java服务器套接字读取
我有一个非常特殊的问题,我最后的办法是在 StackOverflow 上询问这个问题,所以请保持开放的态度!
这里有两个程序:
A. 客户端:运行在Android手机上的java客户端。 B. 服务器:运行在计算机上的java服务器。
这两个程序的作用如下:
客户端每 2 毫秒(非常快)发送服务器坐标(字符串格式),并且服务器必须读取客户端发送给它的所有这些坐标。为了实现这一点(假设服务器位于 10.0.0.1 并正在侦听端口 54321),服务器必须有一个套接字,通过该套接字读取所有传入信息。是的,它确实收到了所有信息,但是,有一个问题!
现在您已经了解了故事背后的背景,问题是:
客户端连接到服务器,一旦发生这种情况,它就开始以极快的速度发送坐标(以字符串格式)。服务器确实获取了所有消息,但除非客户端断开连接,否则它不会停止读取。我需要的是服务器在收到时单独读取每条消息!
这是我用来从套接字读取的代码(这是针对服务器的,它在自己的线程上):
while(true) {
try {
BufferedReader socketReader =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = socketReader.readLine();
System.out.println("New Message: " + str);
socketReader.close();
} catch (IOException e) {
//Client disconnected
System.out.println("Client disconnected.");
break;
}
}
这是我从客户端获得的输出(其中 x 和 y 是数字):
New Message: x,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,y...and so on
并且仅包含文本在客户端断开连接后显示。我希望它在消息进来时显示出来。
只是为了澄清一下,这是所需的输出:
New Message: x,y
New Message: x,y
New Message: x,y
New Message: x,y
... and so on
如果这有任何用处,这里是写入套接字的方法(此代码来自客户端)
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
while(running) {
writer = new PrintWriter(socket.getOutputStream(), true);
writer.write(x+","+y);
writer.flush();
}
所以全部都在所有,我需要的是我的服务器在消息进来时读取消息,而不是在客户端断开连接后同时读取所有消息。 PS 在 C# 中,我还编写了一个服务器,该服务器读取传入的信息,但在 Java 中这行不通!
I have a very peculiar problem and my last resort was asking this on StackOverflow, so please be open minded!
Here are two programs:
A. Client: A java client running on an Android phone.
B. Server: A java server running on a Computer.
Here is what the two programs do:
Client sends server coordinates (in string format) every 2 milliseconds (very fast), and the server must read all those coordinates that the client sends it. In order to achieve this (given that the server is located at 10.0.0.1 and is listening on port 54321), the server must have a socket via which it reads all the incoming info. And yes, it does receive all of the information, BUT, there is a catch!
Now that you have the background behind the story, here is the problem:
The client connects to the server and as soon as that happens,it starts sending coordinates (in string format) at an extremely fast rate. The server does get all the messages, but it does not stop reading unless the client has disconnected. What i need is for the server to read every single message individually as they received!
Here is the code i used to read from the socket (this is for the server, and it is on its own thread):
while(true) {
try {
BufferedReader socketReader =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = socketReader.readLine();
System.out.println("New Message: " + str);
socketReader.close();
} catch (IOException e) {
//Client disconnected
System.out.println("Client disconnected.");
break;
}
}
This is the output i am getting from the client (where x and y are numbers):
New Message: x,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,yx,y...and so on
And that text only shows up AFTER the client has disconnected. I want it to show up AS THE MESSAGES come in.
Just to clarify, this is the desired output:
New Message: x,y
New Message: x,y
New Message: x,y
New Message: x,y
... and so on
In case this is of any use, here is the method of writing to the socket (this code is from the client)
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
while(running) {
writer = new PrintWriter(socket.getOutputStream(), true);
writer.write(x+","+y);
writer.flush();
}
So all in all, what i need is for my server to read the messages as they come in instead of reading them all at the same time after the client disconnects. P.S in C# i have also written a server and that one reads the info as it comes in, but in Java this isnt working out!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在调用 readLine< /a>,顾名思义,用于读取行。您的数据不由行组成。
如果可能,请更改您的协议,以便每组坐标均以换行符和/或回车符终止。
不幸的是,我认为你无法让它发挥作用。 2ms 的分辨率在商用网络硬件上是不可能的,如果你试图强制它,各种事情都会崩溃。如果启用 Nagle,当 ACK 延迟时,您会从 Nagle 获得 200 毫秒的延迟。如果禁用 Nagle,丢弃数据包将使延迟急剧上升。
老实说,我会撕毁设计并开始重新思考您的需求是什么以及如何满足它们。
你在哪里找到每秒可以发送 500 个数据包的 Android 设备?!据我所知,没有任何 Wifi 可以做到这一点,而且通过电线的 GPS 有什么用呢?
(如果您还没有执行诸如将套接字缓冲区缩小到绝对最小值、使用非阻塞写入操作以及通过中止和删除接收器中的部分数据来处理部分写入等操作,那么您将无法满足您的要求如果连接带宽暂时下降,您不得让数据备份。)
You are calling readLine which, as its name suggests, is for reading lines. Your data does not consist of lines.
If possible, change your protocol so that each set of coordinates is terminated by a newline and/or carriage return.
Unfortunately, I don't think you're going to be able to get this to work. 2ms resolution is just not possible over commodity network hardware and all kinds of things will break if you try to force it. If you enable Nagle, you'll get 200ms delays from Nagling when an ACK is late. If you disable Nagle, dropping a data packet will shoot your latency through the roof.
Honestly, I'd rip up the design and start over thinking through precisely what your requirements are and how you're going to meet them.
Where did you find an Android device that can send 500 packets a second?! No Wifi I know of can do that, and what use is GPS over a wire?
(If you're not already doing things like shrinking socket buffers to the absolute minimum, using non-blocking write operations, and handling partial writes by aborting and dropping partial data in the receiver, you won't get anywhere close to meeting your requirements. You must not let data back up if there's a momentary drop in connection bandwidth.)
每次在客户端的输出套接字上执行一次
flush()
。这些消息实际上正在缓冲,直到您现在关闭套接字为止。Do a
flush()
on your output socket in your client each time. The messages are actually being buffered until you close the socket now.