Socket socket = new Socket("192.168.178.47", 82);
OutputStream out = socket.getOutputStream();
out.write("{ \"phone\": \"23456789\" }".getBytes());
out.flush();
//服务器
InputStream in = client.getInputStream();
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
int i = 0;
while((i = in.read()) >= 0) {
bOut.write(i);
}
String complete = new String(bOut.toByteArray(), "UTF-8");
我曾尝试通过OutputStream将数据发送到套接字,但数据没有刷新。如果我在末尾添加out.close();
,那么它可以正常工作,但套接字已关闭,我无法接受响应。有人知道为什么吗?服务器没有给出任何类型的错误。我曾经使用过Java 1.7!
答案 0 :(得分:7)
服务器可能正在等待行尾。如果是这种情况,请在文本中添加“\ n”
答案 1 :(得分:3)
我不确定你问题中的“// Server”标签,但我假设以下代码是服务器代码:
InputStream in = client.getInputStream();
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
int i = 0;
while((i = in.read()) >= 0) {
bOut.write(i);
}
String complete = new String(bOut.toByteArray(), "UTF-8");
这将继续读取,每次都阻塞,直到它从read()
得到的值小于零。只有在流关闭时才会发生这种情况。
看起来你需要建立自己的协议。因此,不是寻找“< = 0”而是寻找一些表示消息结束的常量值。
这是我的意思的快速演示(我昨天没有时间)。我有3个班级,Message
,MyClient
(也是main
班级)和MyServer
。请注意,发送或接收换行没有任何意义。什么都没有设置tcpNoDelay。但它运作正常。其他一些说明:
Message
实例。这需要检查Message
以及结束的开始。 Message
上课:
public class Message {
public static final String MSG_START = "<message>";
public static final String MSG_END = "</message>";
private final String content;
public Message(String string){
content = string;
}
@Override
public String toString(){
return MSG_START + content + MSG_END;
}
}
MyServer
上课
public class MyServer implements Runnable{
public static final int PORT = 55555;
@Override
public void run(){
try {
ServerSocket serverSocket = new ServerSocket(PORT);
Socket socket = serverSocket.accept();
String message = getMessage(socket);
System.out.println("Server got the message: " + message);
sendResponse(socket);
}catch (IOException e){
throw new IllegalStateException(e);
}
}
private void sendResponse(Socket socket) throws IOException{
Message message = new Message("Ack");
System.out.println("Server now sending a response to the client: " + message);
OutputStream out = socket.getOutputStream();
out.write(message.toString().getBytes("UTF-8"));
}
private String getMessage(Socket socket) throws IOException{
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
StringBuilder sb = new StringBuilder(100);
byte[] bytes = new byte[1024<<8];
while(sb.lastIndexOf(Message.MSG_END) == -1){
int bytesRead = in.read(bytes);
sb.append(new String(bytes,0,bytesRead,"UTF-8"));
}
return sb.toString();
}
}
MyClient
上课
public class MyClient {
public static void main(String[] args){
MyClient client = new MyClient();
Thread server = new Thread(new MyServer());
server.start();
client.performCall();
}
public void performCall(){
try {
Socket socket = new Socket("127.0.0.1",MyServer.PORT);
sendMessage(socket, "Why hello there!");
System.out.println("Client got a response from the server: " + getResponse(socket));
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
public String getResponse(Socket socket) throws IOException{
String response;
StringBuilder sb = new StringBuilder(100);
InputStream in = socket.getInputStream();
byte[] bytes = new byte[1024];
while(sb.lastIndexOf(Message.MSG_END) == -1){
int bytesRead = in.read(bytes);
sb.append(new String(bytes,0,bytesRead,"UTF-8"));
}
response = sb.toString();
return response;
}
public void sendMessage(Socket socket, String message) throws IOException{
Message msg = new Message(message);
System.out.println("Client now sending message to server: " + msg);
OutputStream out = socket.getOutputStream();
out.write(msg.toString().getBytes("UTF-8"));
}
}
输出
Client now sending message to server: Why hello there! Server got the message: Why hello there! Server now sending a response to the client: Ack Client got a response from the server: Ack Process finished with exit code 0
答案 2 :(得分:1)
尝试使用
socket.setTcpNoDelay(true);
出于性能原因发生缓冲(阅读Nagle的算法)。
答案 3 :(得分:0)
查看您的代码似乎没问题。然而,你发送的数量少于MTU Nagle的algothrim可能会将其保留,直到有足够的数据存在完整数据包或关闭套接字。
所以 - 试试这个:
socket.setTCPNoDelay(true);
http://en.wikipedia.org/wiki/Nagle%27s_algorithm https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#setTcpNoDelay-boolean-
答案 4 :(得分:0)
这是服务器问题,因为flush
总是强制写入。测试它尝试运行此代码:
public static void main(String[] args) throws IOException, InterruptedException {
Socket socket = new Socket("localhost", 8222);
OutputStream out = socket.getOutputStream();
for (int i = 0; i < 10; i++) {
out.write((i + " : { \"phone\": \"23456789\" }").getBytes());
out.flush();
TimeUnit.SECONDS.sleep(1);
}
}
之前,在shell上运行此命令:
$ nc -l localhost 8222
在端口8222上侦听数据。您将看到每{1}}输出
上显示每1秒数据答案 5 :(得分:0)
问题不在于您没有正确刷新,而是在处理数据之前,读取代码等待套接字断开连接:
while((i = in.read()) >= 0)
只要可以从in
(套接字的InputStream)读取内容,就会循环。在另一个对等设备断开连接之前,该条件不会失败。