java - 如何使此服务器在网络的多台计算机上工作
问题描述
import java.net.*;
import java.io.*;
import java.util.*;
public class GroupChat
{
private static final String TERMINATE = "Exit";
static String name;
static volatile boolean finished = false;
public static void main(String[] args)
{
if (args.length != 2)
System.out.println("Two arguments required: <multicast-host> <port-number>");
else
{
try
{
InetAddress group = InetAddress.getByName(args[0]);
int port = Integer.parseInt(args[1]);
Scanner sc = new Scanner(System.in);
System.out.print("Enter your name: ");
name = sc.nextLine();
MulticastSocket socket = new MulticastSocket(port);
// Since we are deploying
socket.setTimeToLive(0);
//this on localhost only (For a subnet set it as 1)
socket.joinGroup(group);
Thread t = new Thread(new
ReadThread(socket,group,port));
// Spawn a thread for reading messages
t.start();
// sent to the current group
System.out.println("Start typing messages...\n");
while(true)
{
String message;
message = sc.nextLine();
if(message.equalsIgnoreCase(GroupChat.TERMINATE))
{
finished = true;
socket.leaveGroup(group);
socket.close();
break;
}
message = name + ": " + message;
byte[] buffer = message.getBytes();
DatagramPacket datagram = new
DatagramPacket(buffer,buffer.length,group,port);
socket.send(datagram);
}
}
catch(SocketException se)
{
System.out.println("Error creating socket");
se.printStackTrace();
}
catch(IOException ie)
{
System.out.println("Error reading/writing from/to socket");
ie.printStackTrace();
}
}
}
}
class ReadThread implements Runnable
{
private MulticastSocket socket;
private InetAddress group;
private int port;
private static final int MAX_LEN = 1000;
ReadThread(MulticastSocket socket,InetAddress group,int port)
{
this.socket = socket;
this.group = group;
this.port = port;
}
@Override
public void run()
{
while(!GroupChat.finished)
{
byte[] buffer = new byte[ReadThread.MAX_LEN];
DatagramPacket datagram = new
DatagramPacket(buffer,buffer.length,group,port);
String message;
try
{
socket.receive(datagram);
message = new
String(buffer,0,datagram.getLength(),"UTF-8");
if(!message.startsWith(GroupChat.name))
System.out.println(message);
}
catch(IOException e)
{
System.out.println("Socket closed!");
}
}
}
}
是否可以在同一网络的两台计算机上运行此代码?我已经尝试过,但它似乎只有在同一台计算机上才能工作。网络是否存在问题,或者代码是否无法传递到网络中的不同计算机。顺便说一句,这不是我的代码,我是出于学习目的从互联网上获取的。提前非常感谢。
解决方案
是的,在同一网络中的两台计算机之间建立套接字连接绝对是可能的。无论如何,我发现使用java.net.Socket更容易做到这一点,我的例子在这里:(这是一个可继承的类)
/**
*
* @param ipAddress See {@link Client#ipAddress}
* @param port See {@link Client#port}
* @param prints See {@link Client#prints}
* @param printNewline See {@link Client#printNewline}
* @param printColor See {@link Client#printColor}
* @param printViaLogger See {@link Client#printViaLogger}
* @param logger See {@link Client#logger}
*/
public Client(String ipAddress, String port,boolean prints, boolean printNewline, CConsoleColor printColor, boolean printViaLogger,LatestLogger logger) {
this.ipAddress = ipAddress;
this.port = port;
this.prints = prints;
this.printNewline = printNewline;
this.printColor = printColor;
this.printViaLogger = printViaLogger;
this.logger = logger;
}
/**
* This method starts the client
*/
public void connect() {
try {
socket = new Socket();
InetSocketAddress address = new InetSocketAddress(ipAddress,Integer.parseInt(port));
socket.connect(address,5000);
print("Client connected (" + ipAddress + ":" + port + ")");
listening = true;
scanner = new Scanner(new BufferedReader(new InputStreamReader(socket.getInputStream())));
writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
connected = true;
startListening();
} catch (IOException e) {
connected = false;
}
}
/**
*
* @param args String[] has to contain all arguments you want so sent
*/
public void sendPacket(String[] args) {
String sending = "";
/* Getting all args */
for (int i = 0; i < args.length; i++) {
/* Writing current args into the OutputStream */
sending = sending + args[i] + " ";
}
writer.println(sending);
writer.flush();
print("Client (" + socket.getInetAddress() + ") sending new Packet");
}
/**
* This method gets called when the server is started, because this method contains the scanner for the socket-connection
*/
private void startListening() {
new Thread(new Runnable() {
@Override
public void run() {
String incoming;
while (listening) {
if(scanner.hasNextLine() && (incoming = scanner.nextLine()) != null) {
/* Run 'handle' method */
handle(incoming);
print("Client (" + socket.getInetAddress() + ") received a new Packet");
}
}
}
}).start();
}
/**
*
* @param incoming String is the incoming string from the server
*/
public void handle(String incoming) {
/* Empty method to change */
}
这是我的服务器类:
/**
*
* @param socket See {@link Server#socket}
* @param scanner See {@link Server#scanner}
* @param writer See {@link Server#writer}
* @param prints See {@link Server#prints}
* @param printNewline See {@link Server#printNewline}
* @param printColor See {@link Server#printColor}
* @param printViaLogger See {@link Server#printViaLogger}
* @param logger See {@link Server#logger}
*/
public Server(Socket socket, Scanner scanner, PrintWriter writer, boolean prints, boolean printNewline, CConsoleColor printColor,ServerManager manager, boolean printViaLogger, LatestLogger logger) {
/* Defining variables */
this.socket = socket;
this.scanner = scanner;
this.writer = writer;
this.prints = prints;
this.printNewline = printNewline;
this.printColor = printColor;
this.manager = manager;
this.printViaLogger = printViaLogger;
this.logger = logger;
}
/**
* This is the run method of your Serverthread
*/
@Override
public void run() {
/* Create 'incoming' String */
String incoming = null;
while (true) {
/* Searching for next line */
if (scanner.hasNextLine() && (incoming = scanner.nextLine()) != null) {
print("Server (" + socket.getInetAddress() + ") received a new Packet");
/* Run 'handle' method */
manager.handle(incoming,this);
}
}
}
/**
*
* @return {@link Server#socket}
*/
public Socket getSocket() {
return socket;
}
/**
*
* @param args String[] has to contain all arguments of the packet you want to send
*/
public void sendPacket(String[] args) {
String sending = "";
/* Getting all args */
for (int i = 0; i < args.length; i++) {
/* Writing current args into the OutputStream */
sending = sending + args[i] + " ";
}
writer.println(sending);
writer.flush();
print("Server (" + socket.getInetAddress() + ") sending new Packet");
}
这是我的 ServerManager 类:
/**
*
* @param ipAddress See {@link ServerManager#ipAddress}
* @param port See {@link ServerManager#port}
* @param prints See {@link ServerManager#prints}
* @param printNewline See {@link ServerManager#printNewline}
* @param printColor See {@link ServerManager#printColor}
* @param maxConnection See {@link ServerManager#maxConnection}
* @param printViaLogger See {@link ServerManager#printViaLogger}
* @param logger See {@link ServerManager#logger}
*/
public ServerManager(String ipAddress,String port,boolean prints, boolean printNewline, CConsoleColor printColor, int maxConnection, boolean printViaLogger, LatestLogger logger) {
/* Defining variables */
this.ipAddress = ipAddress;
this.port = port;
this.maxConnection = maxConnection;
this.prints = prints;
this.printNewline = printNewline;
this.printColor = printColor;
this.printViaLogger = printViaLogger;
this.logger = logger;
}
/**
* If your want to start the server you have to run this method
*/
public void connect() {
/* Creating new Thread */
new Thread(new Runnable() {
@Override
public void run() {
try {
/* Create variables */
Socket remoteClientSocket;
Scanner scanner;
PrintWriter writer;
print("Server starting...");
/* Creating and Defining ServerSocket variable */
ServerSocket serverSocket = new ServerSocket(Integer.valueOf(port));
print("Waiting for conenctions...");
/* Start listening */
while (true) {
/* Checking limit */
if(connectedClients.size() <= maxConnection) {
/* Limit not fulfill */
/* Defining 'remoteClientSocket' variables */
remoteClientSocket = serverSocket.accept();
print("Client connected: " + remoteClientSocket.getRemoteSocketAddress());
/* Defining 'scanner' variables */
scanner = new Scanner(new BufferedReader(new InputStreamReader(remoteClientSocket.getInputStream())));
/* Defining 'writer' variables */
writer = new PrintWriter(new OutputStreamWriter(remoteClientSocket.getOutputStream()));
server = new Server(remoteClientSocket,scanner,writer,prints,printNewline,printColor,getInstance(),printViaLogger,logger);
/* Starting server */
server.start();
/* Adding server to list */
connectedClients.add(server);
/* Add 1 to maxConnection */
maxConnection++;
}else {
print("Limit reached");
break;
}
}
}catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String exeptionAsString = sw.toString();
print(exeptionAsString);
}
}
}).start();
}
/**
*
* @param incoming String has to be the incoming string from the client
* @param server Server has to be the server from which the packet was received
*/
public void handle(String incoming, Server server) {
// Empty method for handle
}
/**
* If you want to disconnect an client from the server you have to run this method
* @param server The client you want to disconnect
*/
public void disconnectClient(Server server) {
try {
server.getSocket().close();
connectedClients.remove(server);
} catch (IOException e) {
e.printStackTrace();
}
}
几乎所有变量集都被声明但没有值,我希望它对你有帮助
推荐阅读
- python - 超链接创建未按预期工作
- javascript - 在继续之前完成订阅/承诺
- c++ - 函数及其属性的通用存储为元组
- keras - 为什么我有三个不同的 MSE 值
- go - MagickWand 7 API:如何移植 MagickSetImageClipMask 调用
- computational-geometry - CGAL 坐标值转换在 5.2.1 中不再起作用
- reactjs - 无法在类组件中调用 React Hook “React.useState”
- pyopencl - 子类 pyopencl.array.Array
- c# - 虚幻引擎构建在 C# 尝试打开回收站文件时崩溃
- python - 如何将一些字符串更改为字典中的整数?