我有一个小型套接字服务器,我需要根据不同的条件从客户端到客户端分发各种消息。
但是我认为我当前代码中的生动性有一个小问题,我的方法有什么问题:
public class CuClient extends Thread
{
Socket socket = null;
ObjectOutputStream out;
ObjectInputStream in;
CuGroup group;
public CuClient(Socket s, CuGroup g)
{
this.socket = s;
this.group = g;
out = new ObjectOutputStream(this.socket.getOutputStream());
out.flush();
in = new ObjectInputStream(this.socket.getInputStream());
}
@Override
public void run()
{
String cmd = "";
try {
while (!cmd.equals("client shutdown")) {
cmd = (String) in.readObject();
this.group.broadcastToGroup(this, cmd);
}
out.close();
in.close();
socket.close();
} catch (Exception e) {
System.out.println(this.getName());
e.printStackTrace();
}
}
public void sendToClient(String msg)
{
try {
this.out.writeObject(msg);
this.out.flush();
} catch (IOException ex) {
}
}
我的CuGroup:
public class CuGroup
{
private Vector<CuClient> clients = new Vector<CuClient>();
public void addClient(CuClient c)
{
this.clients.add(c);
}
void broadcastToGroup(CuClient clientName, String cmd)
{
Iterator it = this.clients.iterator();
while (it.hasNext()) {
CuClient cu = (CuClient)it.next();
cu.sendToClient(cmd);
}
}
}
我的主要班级:
public class SmallServer
{
public static final Vector<CuClient> clients = new Vector<CuClient>(10);
public static boolean serverRunning = true;
private ServerSocket serverSocket;
private CuGroup group = new CuGroup();
public void body()
{
try
{
this.serverSocket = new ServerSocket(1337, 20);
System.out.println("Waiting for clients\n");
do
{
Socket s = this.serverSocket.accept();
CuClient t = new CuClient(s,group);
System.out.println("SERVER: " + s.getInetAddress() + " is connected!\n");
t.start();
} while (this.serverRunning);
} catch (IOException ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args)
{
System.out.println("Server");
SmallServer server = new SmallServer();
server.body();
}
}
考虑具有更多组的示例,可能是组的集合。如果它们都在一个对象上同步,我认为我的服务器不会很快。
我有一种模式或某种东西可以帮助我的活力吗?
答案 0 :(得分:1)
正确性方面的最大缺陷是ObjectOutputStream不是一个线程安全的类。通过从各种线程调用sendToClient,您已经暴露于一个大的竞争条件,其中两个外发消息相互混合。
两个简单但效率低下的解决方案:1)同步sendToClient,2)为每个从BlockingQueue读取的客户端创建发送方线程,并更改sendToClient以添加到该队列。前者是浪费,因为单个高延迟客户端会使其他客户陷入瓶颈。后者是浪费的,因为它需要双倍的线程。正如@spender所说,asynch IO对于这段代码确实会更好,但它对代码来说肯定不那么直接。
答案 1 :(得分:0)