我正在尝试使用UDP为多个客户端实现Java中的聊天应用程序。我使用线程接受服务器端的输入和另一个线程来处理输入。我的代码是:
服务器端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;
public class ChatServer
{
static DatagramSocket socket;
static DatagramPacket packet;
static ArrayList<InetAddress> arrayList;
static LinkedBlockingQueue<byte[]> messages;
public static void main(String[] args) throws IOException
{
arrayList = new ArrayList<InetAddress>();
messages = new LinkedBlockingQueue<byte[]>();
byte[] b = new byte[500];
System.out.println("Server initialized..");
socket = new DatagramSocket(Integer.parseInt(args[0]));
packet = new DatagramPacket(b, b.length);
Thread acceptorThread = new Thread()
{
public void run()
{
while(true)
{
try
{
socket.receive(packet);
System.out.println("acceptor");
if(arrayList.add(packet.getAddress()))
System.out.println("listtrue");
if(messages.add(packet.getData()))
System.out.println("queuetrue");;
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
};
acceptorThread.start();
Thread messageHandler = new Thread()
{
public void run()
{
System.out.println("handler");
while(true)
{
if(messages.poll() != null)
{
byte []b = "soham".getBytes();
sendAll(b);
}
}
}
};
messageHandler.start();
}
public static void sendAll(byte[] b)
{
for(InetAddress address : arrayList)
{
DatagramPacket packet = new DatagramPacket(b, b.length, address, 4445);
try
{
socket.send(packet);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
socket.close();
}
}
}
}
,客户端是:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class ChatClient {
public static void main(String[] args) throws IOException
{
while(true)
{
//get input
System.out.println("Message:");
Scanner sc = new Scanner(System.in);
String message = sc.next();
// get a datagram socket
DatagramSocket socket = new DatagramSocket();
// send request
byte[] buf = new byte[256];
buf = message.getBytes();
InetAddress address = InetAddress.getLocalHost();
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, Integer.parseInt(args[0]));
socket.send(packet);
// get response
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// display response
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println(packet.getSocketAddress()+" " + received);
}
}
}
执行后的stacktrace给了我:
java.net.SocketException: Socket closed
at java.net.DualStackPlainDatagramSocketImpl.checkAndReturnNativeFD(Unknown Source)
at java.net.DualStackPlainDatagramSocketImpl.receive0(Unknown Source)
at java.net.AbstractPlainDatagramSocketImpl.receive(Unknown Source)
at java.net.DatagramSocket.receive(Unknown Source)
at snippet.ChatServer$1.run(ChatServer.java:40)
我无法确定问题所在。任何帮助都会受到赞赏,欢呼。
答案 0 :(得分:0)
您的sendAll
方法在每个(第一个)发送的数据包之后关闭套接字。
答案 1 :(得分:0)
您误解了finally
区块的含义。它目前在sendAll的每次迭代中执行。您正在关闭每个客户端的套接字,而只应为最后一个客户端执行该套接字。