Java中的多线程UDP聊天应用程序给出java.net.SocketException:Socket关闭

时间:2013-09-14 23:52:41

标签: java sockets udp

我正在尝试使用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)

我无法确定问题所在。任何帮助都会受到赞赏,欢呼。

2 个答案:

答案 0 :(得分:0)

您的sendAll方法在每个(第一个)发送的数据包之后关闭套接字。

答案 1 :(得分:0)

您误解了finally区块的含义。它目前在sendAll的每次迭代中执行。您正在关闭每个客户端的套接字,而只应为最后一个客户端执行该套接字。