这就是我想要实现的目标:
有客户端和服务器套接字。客户端套接字将向服务器发送消息(例如"add:2:3" to add 2 and 3
等)。服务器应该回答一个答案。当答案到达时,客户端可以发送附加消息(如"subtract:5:8" to subtract 5 from 8
)等...因此客户端将发送消息,然后它将得到响应,然后它将发送下一条消息并获得响应我从命令行发送消息。
这就是我现在所拥有的,但它不起作用:
//服务器代码
public class MT extends Thread{
private Socket sock;
private BufferedReader rd;
private OutputStreamWriter wr;
private Client client;
public MT(Socket sock) throws IOException {
this.sock= sock;
rd = new BufferedReader(new InputStreamReader(sock.getInputStream()));
wr = new OutputStreamWriter(sock.getOutputStream());
wr.write("You are welcome" + "\n");
wr.flush();
}
public void run(){
try{
while(true){
String command = reader.readLine();
// Will process data here and then send results to client
// At the moment i just want to send the message back to client
wr.write(command + "\n"); // send results to client
}
}
}
}catch(IOException ex){
System.err.println("Problem reading data from client");
}
}
}
public class MyServio {
public static void main(String[] args) {
try(ServerSocket server = new ServerSocket()){
server.bind(new InetSocketAddress("0.0.0.0", 4444));
System.out.println("Listening...");
try{
while(true){
Socket con = server.accept();
Thread a = new MT(con);
a.start();
}
}catch(IOException ex){
System.err.println("Problem...");
}
}catch(IOException ex){
System.err.println("Server Issues");
}
}
}
//客户端
对于客户端,我决定使用两个线程来读取和写入服务器
public class MyRead extends Thread{
private BufferedReader r;
public ReadFromServer(BufferedReader r){
this.r = r;
}
@Override
public void run() {
StringBuilder m = new StringBuilder();
try {
while(true){
message.append(r.readLine());
System.out.println(m);
}
} catch (IOException e) {
System.out.println("Problem in MyRead");
e.printStackTrace();
}
}
}
public class MyWrite extends Thread{
private OutputStreamWriter w;
Scanner sc;
public WriteToServer(OutputStreamWriter w){
this.w = w;
sc = new Scanner(System.in);
}
@Override
public void run() {
try {
while(true){
System.out.print("Type message: ");
String msg = sc.nextLine();
w.write(msg + "\n");
w.flush();
}
} catch (IOException e) {
System.out.println("Problem in MyWrite");
e.printStackTrace();
}
}
}
public class CSock {
private OutputStreamWriter w;
private BufferedReader r;
public ClientSocket() {}
public void do(){
InetAddress ad = null;
try {
ad = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e) {
System.err.println("Error InetAddress");
}
try (Socket s = new Socket(addr, PORT)) {
System.out.println("Server connecting...");
StringBuilder message = new StringBuilder();
r = new BufferedReader(new InputStreamReader(s.getInputStream()));
w = new OutputStreamWriter(s.getOutputStream());
message.append(r.readLine()); // reads the welcome message from server
System.out.println(message);
// I start the read and write threads so that the client can read and write message to the server
ReadFromServer rd = new ReadFromServer(r);
WriteToServer wt = new WriteToServer(w);
rd.start();
wt.start();
} catch (IOException ex) {
System.err.println("problem connecting to server");
}
}
}
public class Main {
public static void main(String[] args){
ClientSocket clientSocket = new ClientSocket();
clientSocket.do();
}
}
我首先启动服务器,然后启动客户端,但客户端提供了一个例外:
Problem in MyRead
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at model.ReadFromServer.run(ReadFromServer.java:31)
异常中的最后一行表示代码中的message.append(reader.readLine());
是问题所在。我不会在我的代码中的任何地方关闭套接字或输入流或输出流,但我得到了这个例外。
在以下行socket closed
MyWrite
方法的run()
课程中也会出现类似的writer.flush();
例外情况
答案 0 :(得分:1)
在此行的客户端
try (Socket s = new Socket(addr, PORT)) {
你告诉jvm它应该在执行try语句后关闭套接字。
这一行是从套接字的输出流创建一个阅读器。
r = new BufferedReader(new InputStreamReader(s.getInputStream()));
这是创建一个从服务器读取的功能。
ReadFromServer rd = new ReadFromServer(r);
ReadFromServer是一个线程,在try-catch语句完成后可以自由执行。因此,当它执行reader.readLine()
时,套接字将被关闭。
答案 1 :(得分:0)
您关闭了套接字,然后继续使用它。 try-with-resource语句关闭了套接字;你开始使用的两个线程继续使用它。