gpt4 book ai didi

java - 客户端不从套接字读取数据?

转载 作者:搜寻专家 更新时间:2023-11-01 02:23:02 26 4
gpt4 key购买 nike

我看了其他帖子,好像没有人和我有同样的情况。我已经尝试了所有我读过的解决方案,但都没有结果,所以我决定创建这个问题。

我一直在做服务器/客户端应用程序,客户端似乎无法从套接字读取数据,但服务器可以读取客户端发送的数据。客户端在尝试读取该行时卡住。这是我的代码:

客户:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;

public class Main {

public static Socket s = connect();

public static void sendMessage(String msg) {
if (s != null) {
PrintWriter outWriter = null;
try {
outWriter = new PrintWriter(s.getOutputStream(), true);
outWriter.println(msg);
outWriter.flush();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
outWriter.close();
} finally {
}
} else {
System.err.println("Error, socket is null!");
}
}

public static String readMessage() {
if (s != null) {
Scanner in = null;
try {
in = new Scanner(s.getInputStream());
} catch (IOException ex) {
ex.printStackTrace();
}
String ss = "";
while (in.hasNext()) {
ss += in.next();
}
System.out.println("REPONSE:" + ss);
return ss;
} else {
System.err.println("Error, socket is null!");
}
return "err/readMessage";
}

public static Socket connect() {
try {
Socket sss = new Socket("localhost", 25586);
sss.setKeepAlive(true);
return sss;
} catch (IOException ex) {
ex.printStackTrace();
System.exit(-1);
}
return null;
}

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {

Thread t = new Thread(new Runnable() {
@Override
public void run() {
sendMessage("HELO");
System.out.println("Thread initialized.");

while (true) {
try {
System.out.println("Awaiting message...");
Thread.sleep(100);
String messages = readMessage();
System.out.println("Message recieved! '" + messages + "'");
String[] message = messages.split("/");
System.out.println(messages);
if (message[0].equalsIgnoreCase("DERP")) { // err/reason
System.out.println("IT'S FINALLY WORKING!");
} else {
System.out.println("Didn't work :( response:" + messages);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}

}
}
});
t.start();
}
});
}
}

服务器:

import java.util.List;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main { /* SERVER */


public static List<EchoThread> list = new ArrayList<>();

public static int PORT = 25586;

public static void main(String[] args) throws IOException {
new Main(PORT);
}

public Main(int port) throws IOException {
this.PORT = port;
ServerSocket serverSocket = null;
Socket socket = null;

try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();

}
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
System.out.println("I/O error: " + e);
}
// new threa for a client
EchoThread s = new EchoThread(socket);
s.start();
list.add(s);
}
}

public static void sendMessageToAll(String ss) {
for (EchoThread s : list) {
s.allMessage(ss);
}
}
}

class EchoThread extends Thread {

protected Socket socket;
InputStream inp = null;
BufferedReader brinp = null;

public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
try {
inp = socket.getInputStream();
brinp = new BufferedReader(new InputStreamReader(inp));
} catch (IOException e) {
e.printStackTrace();
}
}

public void run() {
String line;
while (true) {
try {
line = brinp.readLine();
if ((line == null) || line.equalsIgnoreCase("EXIT")) {
socket.close();
return;
} else {
handle(line);
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}

public void handle(String s) {
String[] keys = s.split("/");
System.out.println("random: Handling request\"" + s + "\"");
System.out.println("Response: DERP");
if (s.equalsIgnoreCase("HELO")) {
System.out.println("Message recieved:" + s);
}
respond("DERP");
}

public void respond(String s) {
try {
System.out.println("Response_WILLBE:" + s);
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os, true);
pw.println(s);
pw.flush();
System.out.println("Message sent!");
} catch (Exception ex) {
Logger.getLogger(EchoThread.class.getName()).log(Level.SEVERE, null, ex);
}
}

public void allMessage(String s) {
respond(s);
}
}

我尝试了 flush() 代码以及 \r\nprintln 修复,但都没有用!-- 感谢阅读!

最佳答案

我很好奇客户端和服务器通信方式的区别。例如,客户端使用 Scanner 读取输入,而服务器使用 BufferedReader(这是我个人的偏好)。只是一个建议:保持一致。

现在 -- 首先,客户端只发送一条消息,然后开始无限循环地无限读取。鉴于您确切地知道在向服务器发送“HELO”后服务器应该如何响应(它应该以一行“DERP”响应),因此没有理由在任何循环中从服务器读取数据。

服务器上存在同样的问题。由于客户端现在,它总是只向服务器发送一行(“HELO”)。因此,服务器应该只期望一行并且只读取一行。绝对没有理由在循环中读取输入。但是,实际问题只存在于客户端的代码中:

您当前将 while(in.hasNext()) 作为客户端将从服务器读取输入的时间长度的条件。 The hasNext method differs in logical function depending on the method of communication.在套接字通信的情况下,hasNext 需要一个流,因此,除非套接字关闭,否则将始终返回 true。

通常避免在套接字通信中使用循环,除非您不知道要读取多少行。在这种情况下,您应该首先让发送方向接收方发送某种数字,然后接收方应该在 for 循环中读取后续行读取“n”次(其中 n 是接收到的数字)。

这是一个使用 PrintWritersBufferedReaders 的非常基本的客户端/服务器通信程序。

客户端

public static void main(String[] args){
try{
Socket socket = new Socket("localhost", 12345);
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.write("HELO\n"); //print("HELO\n") and println("HELO") should work too.
out.flush();
System.out.println("Server says " + in.readLine());
in.close();
out.close();
socket.close();
}catch(IOException e){e.printStackTrace();}
}

服务器

public static void main(String[] args){
try{
ServerSocket serverSocket = new ServerSocket(12345);
while(true){
new Thread(new ClientConnectionThread(serverSocket.accept())).start();
}
}catch(IOException e){e.printStackTrace();}
}

private class ClientConnectionThread implements Runnable{
private Socket socket;
public ClientConnectionThread(Socket socket){
this.socket = socket;
}
@Override
public void run(){
try{
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
System.out.println("Client says " + in.readLine());
out.write("HELO Back!\n"); //again, print("HELO Back!\n") and
//println("HELO Back!") should also work
out.flush();
out.close();
in.close();
socket.close();
}catch(IOException e){e.printStackTrace();}
}
}

请注意,在实际通信中不需要循环。

关于java - 客户端不从套接字读取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33978120/

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