我正在尝试用Java创建一个多客户端/服务器应用程序。我遇到了一些问题,因为我的线索似乎纠缠在一起......这就是我想要做的事情。
我有一个Server类,它使用这段代码接受客户端:
而(真){ 套接字socket = serverSocket.accept(); }
我的服务器应该记住连接的客户端,因此我使用该套接字创建一个名为ClientThread的新线程,并将该线程放在服务器上的列表中
该线程侦听从客户端发送的Command对象。如果它收到命令,则需要将其发送到Server实例以进行进一步处理(不在该ClientThread上创建新的Server实例)。我试图通过在创建时将Server-instance添加到此Thread来实现此目的。 (这是正确的方法吗?)
我的服务器也应该能够随时将对象发送回客户端(1个或更多)。我正在尝试使用保存在ClientThread中的socket.getOutputStream()
我应该如何组织我的线程,以便每个客户端始终监听从服务器接受对象,以及他们可以随时将对象发送到服务器。
我知道这不是一个特定的问题,但是如果你知道一些可能对这个用例有用的信息或教程,我真的很感激。
顺便说一句:我知道如何创建套接字和发送(可序列化)对象等等。我只是坚持如何组织一切答案 0 :(得分:1)
您似乎纠结了线程和对象。我会
a)确保你没有在任何地方扩展Thread或调用你的对象XxxxThread。使用ExecutorService来管理线程是一个好主意。
b)有一个简单的模型用于响应客户端命令,例如:每个客户端线程读取一个任务,然后执行任务。
c)为每个连接都有一个包装器,例如使用sendMessage方法。
答案 1 :(得分:1)
既然您已经了解了套接字和线程,我就向您发送了伪代码的想法(案例需要特定部分代码才能告诉我)
你没有提到的一件事是如何通过其IP或任何其他方法(如ID)跟踪客户端?任何给定的设备都可以使用不同的客户端ID打开多个连接吗?或者你只能接受每个设备一个连接?在任何情况下,如果客户已经在列表中,您需要做什么?你会把创建的线程传递给新套接字吗?你会破坏那个线程并创建一个新线程吗?或者你可能会忽略这个新请求?
这是我的想法(取自工作申请):
服务器准备服务器套接字并等待接受状态。
一旦客户端连接,服务器启动一个线程来参加客户端传递它刚刚使用accept命令创建的套接字。当访问客户端的线程启动时,它从客户端收到的第一条消息应该是一个密码o特殊签名,让客户端进入(这是可选的)。
服务器代码:
Prepares the server socket which listen in a well known port
Clear client list;
While (!Terminated)
{
// if you want to impose a limit for connections, check it here:
if (Is the list of connected client full?)
{
Sleep(reasonable time in seconds or miliseconds);
continue;
}
ClientSocket = ServerSocket.Accept();
if the client's IP is already in the list
{
depends on what you want to do.
}
else
{
Add client's IP to the list
Start (create) new client Tread(ClientSocket);
}
}
// when server finish
If (client list is not empty?)
{
Kill all threads
or
Wait until all threads are done
or
Wait an amount of time and then kill those remaining.
}
线程客户端代码:
// This is optional, just to make sure a valid client is connected
Read packet from ClientSocket
if (!Is_the_passport_packet)
{
close socket;
return;
}
// if passport is not required, start here
Try
{
While (!Terminated)
{
if (read packet from client);
{
switch (packet.Command)
{
// In your question you said you want the Server thread to process the request
// I guess you have your requirements to do so,
// anyway, you must use a mutex o some other synchronization method.
case TASK_1:
[sync] process TASK_1(packet, ClientSocket);
break;
case TASK_2:
[sync] process TASK_2(packet, ClientSocket);
break;
etc ….
case WORK_DONE:
Close Socket;
return;
default:
Log(received an unknown command: packet.command);
break;
}
}
else if (Client has quit (closed/broken socket))
{
// as you may know, a socket is consider shutdown when you received a 0 length data
// and a broken connection when received -1 in either case all you have to do is
Close Socket;
return;
}
}
}
catch (Exception e)
{
Log(received an exception: e.message);
}
finally
{
Remove this client from the client's list
}