私は、サーバーがメッセージをクライアントにエコーバックするTCPクライアントとサーバーを期待するプロジェクトに取り組んでいます。以下は、割り当てからです。
サーバー アプリケーションは、次のことを行う必要があります。
- 既知の IP アドレスとポートで TCP 接続をリッスンする
- そのポートで開始された接続を受け入れる
- クライアントからメッセージを受信し、エコー バックする
- クライアントが接続を切断するまで、これを続けます。
クライアント アプリケーションは、次のことを行う必要があります。
- 既知の IP アドレスとポートでサーバーとの接続を確立する
- メッセージを非同期でサーバーに送信します。メッセージの形式は任意です。ただし、サーバーから返されたときに認識されるように、十分な情報が含まれている必要があります。
サーバー用のコーディングを完了しました。これがクライアント用に思いついたものです。
私の質問:
サーバーがよく知られている IP とポートで TCP 接続をリッスンするとはどういう意味ですか? 私の実装で
ServerSocket
は、サーバーがリッスンするポートを受け入れるものを使用しました。私はそれを正しく解釈しましたか?私の現在の TCPClient の実装では、クライアントはサーバーにメッセージを送信しますが、println() はブロッキング呼び出しのようであり、同期になります。クライアントを非同期にするにはどうすればよいですか?
簡潔にするために、TCPServer のコードを追加していません。必要な場合はお知らせください。
更新* * フィードバックに基づいて、TCPClient クラスで変更しました。クライアント要求を受け取った後、ReceiveMessage と SendMessage の 2 つのスレッドを生成します。それを行うと、次の例外が発生します。
[Client] Message sent: Message from Client 97
[Client] Message sent: Message from Client 98
[Client] Message sent: Message from Client 99
[Client] Done Sending all the messages
java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at org.chanders.client.ReceiveMessage.run(ReceiveMessage.java:18)
at java.lang.Thread.run(Thread.java:680)
以下は、新しいクライアント コードです。
public class TCPClient {
Socket clientSocket = null;
OutputStream out = null;
BufferedReader in = null;
String message = "Hello from Client";
int messagecount = 100;
// server credentials
private static final String SERVER_ADDRESS = "localhost";
private static final int SERVER_PORT = 50001;
protected void execute() {
try {
clientSocket = new Socket(SERVER_ADDRESS, SERVER_PORT);
Thread send = new Thread(new SendMessage(clientSocket.getOutputStream()));
Thread receive = new Thread(new ReceiveMessage(clientSocket.getInputStream()));
send.start();
receive.start();
//For server to wait until send and receive threads finish
send.join();
receive.join();
} catch (UnknownHostException uhe) {
System.err.println("Couldnt find host: " + SERVER_ADDRESS);
uhe.printStackTrace();
System.exit(-1);
}catch(IOException ioe) {
System.err.println("Couldnt get I/O: " + SERVER_ADDRESS);
ioe.printStackTrace();
System.exit(-1);
}catch(InterruptedException ie) {
System.err.println("Thread.join failed: ");
ie.printStackTrace();
System.exit(-1);
}
finally {
//cleanup();
}
}
private void cleanup() {
try {
clientSocket.close();
}catch(Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
public static void main(String[] args) {
TCPClient client = new TCPClient();
client.execute();
}
public class SendMessage implements Runnable {
OutputStream out = null;
String message = "Message from Client";
int messageCount = 100;
public SendMessage(OutputStream out) {
this.out = out;
}
public void run() {
PrintWriter writer = new PrintWriter(out);
try {
for (int i = 0; i < messageCount; i++) {
String m = message + " " + i;
writer.println(m);
System.out.println("[Client] Message sent: " + m);
}
System.out.println("[Client] Done Sending all the messages");
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
} finally {
cleanup();
}
}
private void cleanup() {
try {
out.close();
}catch(Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
}
public class ReceiveMessage implements Runnable {
InputStream in = null;
String message;
public ReceiveMessage(InputStream in) {
this.in = in;
}
public void run() {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
try {
while ((message = reader.readLine()) != null) {
System.out.println("[Client] Received message from Server: "
+ message);
}
System.out.println("[Client] Done Receiving messages from Server");
} catch (Exception e) {
e.printStackTrace();
} finally {
cleanup();
}
}
private void cleanup() {
try {
in.close();
}catch(Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
}