多线程程序中的意外I / O中断

时间:2015-04-02 03:28:06

标签: java multithreading

好的,所以我一直遇到一些问题让我的代码工作,所以我制作了一个简化版本的程序来弄清楚发生了什么,但我仍然感到困惑。

以下是该计划:

这是服务器代码:

public class Server{

    private ServerSocket server;
    private Socket connection;
    private DatagramSocket server_socket;
    String compString = "";
    public static List<String> messages = Collections.synchronizedList(new ArrayList<String>());
    public static List<DatagramPacket> packets = Collections.synchronizedList(new ArrayList<DatagramPacket>());


    public Server()
    {               
    }

    public void startRunning()
    {
            try
            {
                server_socket = new DatagramSocket(9876);       
                receiveAndSend();               
            }catch(Exception e)
            {
                System.out.println("Exception caught");
            }
    }

    public void receiveAndSend()
    {
        Thread thread1 = new Thread() 
        {
            public void run() 
            {
                try{
                while(true)
                {
                    byte[] buffer = new byte[3000];
                    DatagramPacket request = new DatagramPacket(buffer, buffer.length);
                    server_socket.receive(request);   
                    String mess = new String(request.getData());                        
                    synchronized(messages)
                    {
                        if(!messages.contains(mess) && !packets.contains(request))
                        {                               
                            addMessage(mess);
                            addPacket(request);                             
                            System.out.println("added: " + mess);               
                        }               
                    }                       
                }
                }catch(Exception e) 
                {
                    System.out.println("Exception caught");
                }           
            }            
        };  
        thread1.start();            
        Thread thread2 = new Thread() 
        {    
            public void run() 
            {
                try
                {
                    while(true)
                    {
                        Thread.sleep(6000);         
                        System.out.println("the list contains");                            
                        synchronized(messages)
                        {
                            compString = "";                    
                            for (String st : messages)
                            {       
                                System.out.println(st);
                            }
                            System.out.println("!!!!!!!!!!!!!!!!!!");    

                            if(!messages.isEmpty())
                            {

                                System.out.println(messages.size());                                    

                                for(int i=0; i< messages.size(); i++)
                                {                   
                                    compString += messages.get(i);
                                    compString += "-";

                                }                                                           
                            }                               
                        }                               
                        System.out.println("final string is:" + compString + "\n");                     
                        for(DatagramPacket pack: packets)
                        {
                            try
                            {                   
                                InetAddress add = pack.getAddress();
                                int port = pack.getPort();

                                byte[] tbuffer = compString.getBytes();
                                DatagramPacket reply = new DatagramPacket(tbuffer, tbuffer.length, add, port);
                                server_socket.send(reply);
                            }catch(Exception e)
                            {
                                System.out.println("Exception caught");
                            }

                        }    
                    }                   

                }catch(Exception e) 
                {

                }           
            }            
        };              
        thread2.start();    
    }

    public synchronized void addMessage(String mess)
    {       
        messages.add(mess);
    }
    public synchronized void addPacket(DatagramPacket packet)
    {
        packets.add(packet);
    }       
}

这是客户端代码:

public class Client {

    public String message;
    public int port;
    public int server = 9876;

    public void Client(String message)
    {
        this.message = message;
    }

    public void startRunning()
    {
            serverStart();   
    }


    public void serverStart()
    {
        Thread thread1 = new Thread() 
        {     
            public void run() 
            {
                try{                        
                    DatagramSocket ssocket = new DatagramSocket(port);              
                while(true)
                {                   
                        Thread.sleep(5000);
                        byte [] m =message.getBytes();
                        InetAddress hhost = InetAddress.getByName("127.0.0.1"); //won't be always localh

                        DatagramPacket request = new DatagramPacket(m, m.length, hhost, server);                        
                        ssocket.send(request);

                        System.out.println("sending: " + message + "\n");

                        byte[] buffer = new byte[2000];
                        DatagramPacket reply = new DatagramPacket(buffer, buffer.length);                       
                        ssocket.receive(reply);

                        String receivedString = new String(reply.getData());

                        System.out.println("receivedString : " + receivedString);
                        if(receivedString != null && !receivedString.isEmpty())
                        {


                        }                   

                }
                }catch(Exception e) 
                {
                     System.out.println("Exception caught");
                }


            }
        };

        thread1.start();        

    }

    public String[] convertStringToArray(String tstring)
    {
        tstring.trim();

        String[] sarray = tstring.split("-");

        return sarray;
    }

}

你需要这3个来运行代码:

public class ServerTest {

    public static void main(String[] args)
    {
        Server s = new Server();
        s.startRunning();
    }

}

public class ClientTest2 {

    public static void main(String[] args)
    {
        Client myclient = new Client();
        myclient.message = "Hello";
        myclient.port = 6965;
        myclient.startRunning();            

    }

}

public class ClientTest {

    public static void main(String[] args)
    {
        Client myclient = new Client();
        myclient.message = "Kitty";
        myclient.port = 6646;
        myclient.startRunning();

    }        

}

我运行时得到以下输出:

added: Helloadded: Kittythe list contains
Hello2
final string is:Hellothe list contains
Hello
!!!!!!!!!!!!!!!!!!
2
final string is:Hello
the list contains
Hello
!!!!!!!!!!!!!!!!!!

问题在于:1)println有时会被打断并且永远不会运行,在上面的输出中我们可以看到该行!!!!!!!!!!!!!!有时不打印出来。 2)Arraylist中的某些元素不会被添加或不会被打印。

我确实试图在任何地方放置同步块,但它似乎没有用,以及其他各种没有帮助的东西。

1 个答案:

答案 0 :(得分:0)

您未正确序列化/反序列化字符串。

在您的服务器中,您应指定从接收缓冲区获取的数据的字节范围,以及客户端使用的编码:

String receivedString = new String(reply.getData(), 0, reply.getLength(), "UTF-8");

在您的客户端中,您应指定用于序列化字符串的编码:

byte[] m = message.getBytes("UTF-8");

此外,DatagramPacket.equals()仅进行引用比较(即,只有在传递对自身的引用时才返回true;它不会将另一个数据包中的数据与自己的数据进行比较),所以{{ 1}}永远都是真的。