如何使用java套接字在服务器和客户端之间进行双向通信?我在 Windows 下使用 JDK 17.0.7。
服务器代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
ServerSocket myServerSocket;
MyTestClient[] myTestClients = new MyTestClient[1];
/*
* CAN NOT Access inncer class
* Just create an object, execute from object,
* and create inner object
*/
public static void main(String[] args) {
MyServer myServer = new MyServer();
myServer.start();
}
public void start() {
// TODO Auto-generated method stub
try {
myServerSocket = new ServerSocket(54321);
Socket socketClient;
for (int i=0;i<1;i++) {
socketClient = myServerSocket.accept();
socketClient.setKeepAlive(true);
MyTestClient myTestClient = new MyTestClient("Test", socketClient);
myTestClients[i]=myTestClient;
}
boolean isLoop = true;
int i=0;
while (isLoop) {
String msg = "Hello "+i;
System.out.println("Send to client: "+msg); // debug
myTestClients[0].sendMsg(msg);
int sleepInt = 100;
System.out.println("Sleep "+sleepInt); // debug
try {
Thread.sleep(sleepInt);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String msgClient = myTestClients[0].receiveMsg();
System.out.println(msgClient); // debug
i++;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace(); // debug
}
}
public class MyTestClient {
public String name;
public Socket clientSocket;
OutputStream myOutputStream;
PrintWriter myPW;
BufferedReader myBR;
public MyTestClient(String name, Socket clientSocket) throws IOException {
this.name = name;
this.clientSocket = clientSocket;
myOutputStream = clientSocket.getOutputStream();
myPW = new PrintWriter(myOutputStream);
myBR = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
public void sendMsg(String msg) throws IOException {
myPW.println(msg);
myPW.flush();
}
public String receiveMsg() throws IOException {
String str = myBR.readLine();
StringBuffer sb = new StringBuffer();
while(str!=null) {
if (str.equals("END")) {
return str;
}
System.out.println(str);
sb.append(str);
str = myBR.readLine();
}
return sb.toString();
}
}
}
客户端代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class MyClient {
InetAddress myServer;
int myPort = 54321;
Socket mySocket;
OutputStream myOutputStream;
PrintWriter myPW;
BufferedReader myBR;
/*
* CAN NOT Access inncer class
* Just create an object, execute from object,
* and create inner object
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyClient myClient = new MyClient();
myClient.start();
}
public void start() {
try {
myServer = InetAddress.getLocalHost();
mySocket= new Socket(myServer,myPort);
myOutputStream = mySocket.getOutputStream();
myPW = new PrintWriter(myOutputStream);
myBR = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
for (int i=0;i<5;i++) {
String msg = receiveMsg();
System.out.println(msg); // debug
int sleetInt = 1000;
try {
Thread.sleep(sleetInt);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
msg = msg+" from Client";
System.out.println(msg); // debug
sendMsg(msg);
}
mySocket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void sendMsg(String msg) throws IOException {
myPW.println(msg);
myPW.flush();
}
private String receiveMsg() throws IOException {
String str = myBR.readLine();
StringBuffer sb = new StringBuffer();
while(str!=null) {
if (str.equals("END")) {
return str;
}
System.out.println(str);
sb.append(str);
str = myBR.readLine();
}
return sb.toString();
}
}
服务器中的结果
>java MyServer
Send to client: Hello 0
Sleep 1000
客户端结果
>java MyClient
Hello 0
它没有按预期循环 5 次。谁能帮我看看代码哪里错了?我需要在客户端创建ServerSocket来接受来自服务器的命令吗?谢谢你
我期望服务器中的输出(调试):
Send to client: Hello 0
Hello 0 from Client
Send to client: Hello 1
Hello 1 from Client
Send to client: Hello 2
Hello 2 from Client
...
我期望客户端中的输出(调试):
Hello 0
Hello 0 from Client
Hello 1
Hello 1 from Client
Hello 2
Hello 2 from Client
...
为了实现2路连接,我们需要在客户端创建套接字。如果局域网游戏连接有回合基地,我们可以控制哪个客户端应该回合。
这是服务器的代码:
package com.dedetok.lancardgame.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer2 {
int serverPort = 54321;
ServerSocket serverSocket;
int clientPort = 54322;
Socket clientSocket;
InetAddress clientInetAddress;
Socket clientConnectionSocket;
OutputStream myOutputStream;
PrintWriter myPW;
BufferedReader myBR;
public static void main(String[] args) {
// TODO Auto-generated method stub
MyServer2 myServer2 = new MyServer2();
myServer2.start();
}
public void start() {
try {
System.out.println("Start server"); // debug
serverSocket = new ServerSocket(serverPort);
boolean isLoop = true;
while (isLoop) {
clientConnectionSocket = serverSocket.accept();
clientInetAddress = clientConnectionSocket.getInetAddress();
myOutputStream = clientConnectionSocket.getOutputStream();
//myPW = new PrintWriter(myOutputStream);
//myPW = new PrintWriter(myOutputStream, true);
myBR = new BufferedReader(new InputStreamReader(clientConnectionSocket.getInputStream()));
StringBuffer sb = new StringBuffer();
String stringFromClient = myBR.readLine();
while (stringFromClient!=null) {
sb.append(stringFromClient);
stringFromClient = myBR.readLine();
}
String stringClient = sb.toString();
System.out.println(stringClient); // debug
myBR.close();
//myPW.close();
if (stringClient.equals("END")) {
stringServer = stringClient;
myServerRun.run();
isLoop = false;
} else {
stringServer = "From Server: "+stringClient;
myServerRun.run();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String stringServer;
Runnable myServerRun = new Runnable() {
@Override
public void run() {
try {
// TODO Auto-generated method stub
clientSocket = new Socket(clientInetAddress, clientPort);
myOutputStream = clientSocket.getOutputStream();
myPW = new PrintWriter(myOutputStream);
//myPW = new PrintWriter(myOutputStream, true);
//myBR = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
myPW.println(stringServer);
myPW.flush();
myPW.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
客户
package com.dedetok.lancardgame.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class MyClient2 {
int serverPort = 54321;
Socket serverSocket;
int clientPort = 54322;
ServerSocket clientSocket;
InetAddress serverInetAddress;
OutputStream myOutputStream;
PrintWriter myPW;
BufferedReader myBR;
int myCounter = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
MyClient2 myClient2 = new MyClient2();
myClient2.start();
}
public void start() {
try {
serverInetAddress = InetAddress.getLocalHost(); // the same host
myClientRun.run();
clientSocket = new ServerSocket(54322);
boolean isLoop = true;
while (isLoop) {
serverSocket = clientSocket.accept();
serverInetAddress = serverSocket.getInetAddress();
//myPW = new PrintWriter(myOutputStream);
//myPW = new PrintWriter(myOutputStream, true);
myBR = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
StringBuffer sb = new StringBuffer();
String stringFromServer = myBR.readLine();
while (stringFromServer!=null) {
sb.append(stringFromServer);
stringFromServer = myBR.readLine();
}
String stringServer = sb.toString();
System.out.println(stringServer); // debug
myBR.close();
if (!stringServer.equals("END")) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myClientRun.run();
} else {
isLoop = false;
System.out.println("myCounter: "+myCounter); // debug
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Runnable myClientRun = new Runnable() {
@Override
public void run() {
try {
// TODO Auto-generated method stub
serverSocket = new Socket(serverInetAddress, serverPort);
myOutputStream = serverSocket.getOutputStream();
myPW = new PrintWriter(myOutputStream);
//myPW = new PrintWriter(myOutputStream, true);
//myBR = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String stringClient = "Hello #: "+myCounter;
if (myCounter==5) {
stringClient = "END";
}
myPW.println(stringClient);
myPW.flush();
myPW.close();
myCounter++;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
客户端可以使用与服务器端口相同的端口来侦听传入的端口,只要它运行在具有不同 IP 的单独设备上即可。