java - 将具有不同 IP 的多个客户端模拟到服务器套接字
问题描述
我有一个接受多个客户端的服务器套接字应用程序。我想用java编写客户端应用程序,将请求发送到服务器应用程序。有什么方法可以模拟具有不同 IP 的多个客户端到服务器应用程序
谢谢,维诺迪尼。
解决方案
请检查以下方法是否对您有帮助?
我已经在同一台机器上验证了 Linux 上的解决方案。
我的 Linux 机器只有一个 NIC(网络接口卡)。
/sbin/ifconfig
eth0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:10.x.x.x Bcast:x.x.x.x Mask:255.255.x.xx
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.x.x.x
我已经暂时给这个网卡添加了多个 IP 地址
您可以使用“ifconfig”命令将 IP 地址添加到 NIC。但请注意,重启机器后该 IP 地址将不可用。在这里,我们假设您已经有一个配置了静态 IP 的 NIC。如果我们需要再添加两个 IP 地址,比如 192.168.1.25 和 192.168.1.26 到这个接口,我们可以通过以 root 用户执行以下命令来完成:
ifconfig eth0:1 192.168.1.25 netmask 255.255.255.0
ifconfig eth0:2 192.168.1.26 netmask 255.255.255.0
帖子补充:
/sbin/ifconfig
eth0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:10.x.x.x Bcast:x.x.x.x Mask:255.255.x.xx
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.x.x.x
eth0:1 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:192.168.1.25 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
eth0:2 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:192.168.1.27 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
现在我的 Linux 主机有 2 个额外的临时 IP 地址。
我在我的 Linux 机器上运行以下服务器套接字程序
远程文件服务器.java
package socket.learning;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
public class RemoteFileServer {
public static void main(String[] args) {
RemoteFileServer server = new RemoteFileServer();
server.acceptConnections(Integer.parseInt(args[0]));
}
public void acceptConnections(int listenPort) {
try {
ServerSocket server = new ServerSocket(listenPort);
Socket incomingConnection = null;
while (true) {
incomingConnection = server.accept();
handleConnection(incomingConnection);
}
} catch (BindException e) {
System.out.println("Unable to bind to port " + listenPort);
} catch (IOException e) {
System.out.println("Unable to instantiate a ServerSocket on port: "
+ listenPort);
}
}
public void handleConnection(Socket incomingConnection) {
try {
System.out.println("Client socket details: getInetAddress "
+ incomingConnection.getInetAddress()
+ " getLocalAddress "
+ incomingConnection.getLocalAddress()
+ " getRemoteSocketAddress "
+ incomingConnection.getRemoteSocketAddress());
OutputStream outputToSocket = incomingConnection.getOutputStream();
InputStream inputFromSocket = incomingConnection.getInputStream();
BufferedReader streamReader = new BufferedReader(
new InputStreamReader(inputFromSocket));
String fileName = streamReader.readLine();
FileReader fileReader = new FileReader(new File(fileName));
BufferedReader bufferedFileReader = new BufferedReader(fileReader);
PrintWriter streamWriter = new PrintWriter(outputToSocket);
String line = null;
while ((line = bufferedFileReader.readLine()) != null) {
streamWriter.println(line);
}
fileReader.close();
streamWriter.close();
streamReader.close();
} catch (Exception e) {
System.out.println("Error handling a client: " + e);
}
}
}
执行:
java -cp . socket/learning/RemoteFileServer 9999
9999 是服务器套接字绑定/监听端口。
在我的 Linux 机器上运行以下客户端套接字程序
使用以下 Socket 构造函数将客户端套接字绑定到本地地址
public Socket(InetAddress address,
int port,
InetAddress localAddr,
int localPort)
throws IOException
Creates a socket and connects it to the specified remote address on the specified remote port. The Socket will also bind() to the local address and port supplied.
If the specified local address is null it is the equivalent of specifying the address as the AnyLocal address (see InetAddress.isAnyLocalAddress()).
A local port number of zero will let the system pick up a free port in the bind operation.
If there is a security manager, its checkConnect method is called with the host address and port as its arguments. This could result in a SecurityException.
Parameters:
address - the remote address
port - the remote port
localAddr - the local address the socket is bound to, or null for the anyLocal address.
localPort - the local port the socket is bound to or zero for a system selected free port.
远程文件客户端.java
package socket.learning;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class RemoteFileClient {
protected String hostIP;
protected int hostPort;
protected BufferedReader socketReader;
protected PrintWriter socketWriter;
public RemoteFileClient(String hostIP, int hostPort) {
this.hostIP = hostIP;
this.hostPort = hostPort;
}
public static void main(String[] args) {
RemoteFileClient remoteFileClient = new RemoteFileClient(args[0],
Integer.parseInt(args[1]));
remoteFileClient.setUpConnection(args[3]);
String fileContents = remoteFileClient.getFile(args[2]);
remoteFileClient.tearDownConnection();
System.out.println(fileContents);
}
public void setUpConnection(String clientIpAddress) {
try {
Socket client = new Socket(hostIP, hostPort,
InetAddress.getByName(clientIpAddress), 0);
socketReader = new BufferedReader(new InputStreamReader(
client.getInputStream()));
socketWriter = new PrintWriter(client.getOutputStream());
} catch (UnknownHostException e) {
System.out
.println("Error setting up socket connection: unknown host at "
+ hostIP);
} catch (IOException e) {
e.printStackTrace();
System.out.println("Error setting up socket connection: " + e);
}
}
public String getFile(String fileNameToGet) {
StringBuffer fileLines = new StringBuffer();
try {
socketWriter.println(fileNameToGet);
socketWriter.flush();
String line = null;
while ((line = socketReader.readLine()) != null)
fileLines.append(line + "\n");
} catch (IOException e) {
System.out.println("Error reading from file: " + fileNameToGet);
}
return fileLines.toString();
}
public void tearDownConnection() {
try {
socketWriter.close();
socketReader.close();
} catch (IOException e) {
System.out.println("Error tearing down socket connection: " + e);
}
}
}
执行:
java -cp . socket/learning/RemoteFileClient 10.x.x.x 9999 /tmp/test.log 192.168.1.27
java -cp . socket/learning/RemoteFileClient 10.x.x.x 9999 /tmp/test.log 192.168.1.25
java -cp . socket/learning/RemoteFileClient 10.x.x.x 9999 /tmp/test.log 10.x.x.x
java -cp . socket/learning/RemoteFileClient 10.x.x.x 9999 /tmp/test.log 127.0.0.1
对应的服务器控制台输出:
Client socket details: getInetAddress /192.168.1.27 getLocalAddress /10.x.x.x getRemoteSocketAddress /192.168.1.27:14774
Client socket details: getInetAddress /192.168.1.25 getLocalAddress /10.x.x.x getRemoteSocketAddress /192.168.1.25:29188
Client socket details: getInetAddress /10.x.x.x getLocalAddress /10.x.x.x getRemoteSocketAddress /10.x.x.x:42407
Client socket details: getInetAddress /127.0.0.1 getLocalAddress /10.x.x.x getRemoteSocketAddress /127.0.0.1:36002
推荐阅读
- python - 如何通过xlwings模块将pandas数据框的数据连续打印到excel中
- docker - 在 ENTRYPOINT 开始之前将 Env 变量从 initContainer 注入主容器
- jmeter - 403 - 禁止:访问在 JMeter 中被拒绝
- javascript - CSS - 通过.map函数显示项目时旋转动画失去过渡属性
- javascript - Function.prototype.bind() 不接受超过 5 个参数?
- kubernetes - 如何调整 kubernetes.yml 以使 livenessprobe 仅在五次运行状况检查失败后才会失败
- c - 我的代码有什么问题?为什么获取功能不起作用?
- reactjs - 执行 form.submit() 时响应表单解决方法以触发提交事件
- mysql - 使用 Express.js 和 mysql 处理 PATCH 请求
- c++ - 除了方便之外,在 CUDA 中使用 2d 内核是否有优势?