gpt4 book ai didi

java - 套接字客户端永远阻塞

转载 作者:可可西里 更新时间:2023-11-01 02:48:08 25 4
gpt4 key购买 nike

我正在用 Java 编写套接字客户端。在程序中,我想从服务器获取信息。当服务器收到“GET_LIGHTS”命令时,它会以 JSON 格式发回数据。

但在我的代码中,bw.write()bw.flush()socket.close() 之前不起作用.因此,BufferedReader 对象未就绪:br.ready() 返回 false。

我的代码有什么错误吗?

客户端代码如下所示。

package monitor;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;

public class SocketClient {
static private int port;
static private String hostName;
private Socket socket;

public SocketClient(String host, int port) {
this.hostName = host;
this.port = port;
}

// get lights by JSON
public void getLights() {
try {
// generate socket
InetSocketAddress endpoint = new InetSocketAddress(hostName, port);
socket = new Socket();
socket.connect(endpoint);

// setting
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
BufferedWriter bw = new BufferedWriter(out);

InputStreamReader in = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(in);

// send command
bw.write("GET_LIGHTS");
bw.flush();

// receive message from server
System.out.println(br.readLine());

socket.close();

} catch (IOException e) {
e.printStackTrace();
}
}

public void initLights(ArrayList<Light> lights) {
getLights();
}

}

编辑:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class SocketServer extends Thread{
static final int PORT = 44344;
static private ILS ils;
private ServerSocket serverSocket;
private Socket socket;

public SocketServer(ILS ils) {
this.ils = ils;
}
@Override
public void run() {
serverSocket = null;
System.out.println("Server: listening");

try {
serverSocket = new ServerSocket(PORT);
while(true){
socket = serverSocket.accept();

BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
ArrayList<String> cmd = new ArrayList<>();
String in;
while( (in = br.readLine()) != null ){
cmd.add(in);
}
command(cmd);
if( socket != null){
socket.close();
}
}

} catch (IOException e) {
e.printStackTrace();
}

if( serverSocket != null){
try {
serverSocket.close();
serverSocket = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}

// send message to client
private void sendMessage(String str) {
System.out.println(str);
try {
OutputStream output = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(output));
bw.write(str + "¥n");
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}

// error
private void printError(String err) {
String str = "ERROR; ";
str += err;
sendMessage(str);
}

public void command(ArrayList<String> cmd) {
String mode = cmd.get(0);
if(mode == null){

}else switch(mode){
case "MANUAL_SIG-ALL":
System.out.println("全照明一括 信号値指定調光");
manualSigAll(cmd.get(1));
break;
case "MANUAL_SIG-INDIVIDUAL":
System.out.println("全照明独立 信号値指定調光");
manualSigIndividual(cmd.get(1));
break;
case "MANUAL_ID-SIG":
System.out.println("照明ID・信号値指定調光");
manualIDSig(cmd.get(1));
break;
case "MANUAL_ID-RELATIVE":
System.out.println("照明ID・相対信号値指定調光");
break;
case "DOWNLIGHT_ALL":
System.out.println("Downlight: All Control");
downlightAll(cmd.get(1));
break;
case "DOWNLIGHT_INDIVIDUAL":
System.out.println("Downlight: Individual control");
downlightIndividual(cmd.get(1));
break;
case "GET_LIGHTS":
System.out.println("Sending lights via JSON");
sendLights();
break;
default:
System.out.println("Error: 不明なmode command");
}
}

// 全照明一括 信号値指定調光
private void manualSigAll(String sigs) {
if(sigs == null) {
System.out.println("信号値のフォーマットを確認してください");
} else {
ArrayList<Integer> s = new ArrayList<>();
String[] buf = sigs.split(",");
for(String i:buf) s.add(Integer.parseInt(i));
for(Light l: ils.getLights()) {
l.setLumPct((double)s.get(0)/255.0*100.0);
l.setSignal(s.get(0), s.get(1));
}
}
// 調光
ils.downlightDimmer.send();

}

// 全照明独立 信号値指定調光
private void manualSigIndividual(String sigs) {
if(sigs == null) {
System.out.println("信号値のフォーマットを確認してください");
} else {
ArrayList<Integer> s = new ArrayList<>();
String[] buf = sigs.split(",");
for(String i:buf) s.add(Integer.parseInt(i));
for(int i=0; i<ils.getLights().size(); i++) {
ils.getLights().get(i).setSignal(s.get(0), s.get(1));
s.remove(0);
s.remove(0);
}
}
ils.downlightDimmer.send();
}

// 照明ID・信号値指定調光
private void manualIDSig(String sigs) {
if(sigs == null) {
System.out.println("信号値のフォーマットを確認してください");
} else {
ArrayList<Integer> s = new ArrayList<>();
String[] buf = sigs.split(",");
for(String i:buf) s.add(Integer.parseInt(i));
System.out.println(s.get(0));
ils.getLight(s.get(0)).setSignal(s.get(1), s.get(2));
}
ils.downlightDimmer.send();
}

private void downlightAll(String cmd) {
if(cmd == null) {
printError("Check for data command.");
} else {
ArrayList<Double> data = new ArrayList<>();
String[] buf = cmd.split(",");
for(String i:buf) data.add(Double.parseDouble(i));
for(Light l: ils.getLights()) {
l.setLumPct(data.get(0));
l.setTemperature(data.get(1));
}
}
// dimming
ils.downlightDimmer.send();
}

private void downlightIndividual(String cmd) {
if(cmd == null) {
printError("Check for data command.");
} else {
ArrayList<Integer> id = new ArrayList<>();
ArrayList<Double> lumPct = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();

String[] buf = cmd.split(",");
if(buf.length % 3 != 0) {printError("invalid number of data.");}

for(int i=0; i<buf.length/3; i++) {
int n = i*3;
try {
id.add(Integer.parseInt(buf[n]));
lumPct.add(Double.parseDouble(buf[n + 1]));
temp.add(Integer.parseInt(buf[n + 2]));
} catch (Exception e) {
printError(e.getMessage());
return;
}
}

while (id.size() > 0) {
// update light object
Light light = ils.getLight(id.get(0));
light.setLumPct(lumPct.get(0));
light.setTemperature(temp.get(0));

// remove data from array list
id.remove(0);
lumPct.remove(0);
temp.remove(0);
}

// dimming
ils.downlightDimmer.send();

}
}

private void sendLights() {
ObjectMapper mapper = new ObjectMapper();
String json = "";
try {
json = mapper.writeValueAsString(ils.getLights());
} catch (JsonProcessingException e) {
e.printStackTrace();
}

// output
sendMessage(json);
}



}

最佳答案

如果您的服务器正在使用 readLine(),这很可能会阻塞,直到您关闭连接,因为您没有发送一条线。 p>

flush()之前添加bw.newLine()

编辑 正如预测的那样,您的服务器没有发送线路,因此它需要与上述相同的处理方式。但是有一个前面的问题:

while( (in = br.readLine()) != null ){
cmd.add(in);
}

服务器中的这个循环不可能退出直到客户端关闭连接。您应该在服务器中一次处理一行,或者降低您对客户端行为的期望。

关于java - 套接字客户端永远阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45956061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com