ClientGUI在传输一个对象后锁定

时间:2011-12-08 21:10:49

标签: java swing tcp

我通过Socket构建客户端服务器..我通过网络从客户端向服务器发送对象..问题是,在我发送一个对象后,当我尝试发送另一个对象时,clientGUI锁定..我认为这可能与我没有在ClientTransmit类的outputStream上做家务管理有关?有人可以看一下吗?谢谢

    ************** clientGUI ***************

import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class ClientGUI extends JFrame implements ActionListener {
    public static final int defaultWidth = 80, defaultHeight = 40;

       private String streamChoice;

       private FootballStream footyStrm;
       private MusicStream musicStrm;
       private String [] listChoices = {"Football", "Music"};
       private JList streamSelect;
       private List list;

       private Button  clearButton;
       private Button  sendButton;

       private JTextArea messageInput;
       private JScrollPane messageScroll;

       private JTextArea streamDisplay;
       private JScrollPane streamPane;

       private JLabel middleLabel;
       private JLabel bottomLabel;

       public ClientGUI() {
            super("ClientGUI");
            JPanel topPanel = new JPanel();
            JPanel middlePanel = new JPanel();
            JPanel bottomPanel = new JPanel();

            list = new List();
            list.add("damian");
            list.add("conor");
            list.addActionListener(this);          

            streamSelect = new JList(listChoices);
            streamSelect.addListSelectionListener(
                    new ListSelectionListener(){
                        public void valueChanged(ListSelectionEvent e) {                            
                            if (! e.getValueIsAdjusting()){
                          //      System.out.println("here");
                                streamChoice = getStreamChoice();
                                }
                            }       
        });

            messageInput = new JTextArea(7, 20);
            messageInput.setLineWrap(true);         
            messageScroll = new JScrollPane(messageInput, 
                    ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
                    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

            streamDisplay = new JTextArea(7, 20);
            streamDisplay.setLineWrap(true);            
            streamPane = new JScrollPane(streamDisplay, 
                    ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
                    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

            clearButton = new Button("Clear");
            clearButton.setBackground(Color.white);
            clearButton.addActionListener(this);

            sendButton = new Button("Send");
            sendButton.addActionListener(this);

            middleLabel = new JLabel("Enter text: ");
            bottomLabel = new JLabel("Entered messages: ");

            topPanel.add(streamSelect);
            topPanel.add(list);
            topPanel.add(sendButton);           
            topPanel.add(clearButton);
            middlePanel.add(messageScroll);
            middlePanel.add(middleLabel, 0);            
            bottomPanel.add(streamPane);
            bottomPanel.add(bottomLabel, 0);

            this.add(topPanel, BorderLayout.NORTH);
            this.add(middlePanel, BorderLayout.CENTER);
            this.add(bottomPanel, BorderLayout.SOUTH);

            this.setSize(400, 400);
            this.setVisible(true);

            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
       }


 public static void main(String[] args) {
    new ClientGUI();
}


@Override
 public void actionPerformed(ActionEvent e) {

    ClientTransmit ct = new ClientTransmit();
    String message = messageInput.getText();

    if(e.getSource()== sendButton){

        if(streamChoice.equals("football")){
            footyStrm = new FootballStream();
            footyStrm.footyVector.add(message);
    //      System.out.println("footy vector element 1 = " + 
    //              footyStrm.messageStream.firstElement());
    //      listElements(footyStrm);
            ct.messageTransmit(footyStrm);
        }

        else if(streamChoice.equals("music")){
            musicStrm = new MusicStream();
            musicStrm.musicVector.add(message);
    //      System.out.println("music vector element 1 = " + 
    //              musicStrm.musicVector.firstElement());  
            ct.messageTransmit(musicStrm);
        }
    }   
 }

 public String getStreamChoice(){

     String choice = null;

    if(streamSelect.getSelectedValue().equals("Football")){
        choice = "football";
        System.out.println("Football");
        return choice;
    }
    else{
        System.out.println("Music");
        choice = "music";
        return choice;
    }   
 }

************** ClientTransmit **************

import java.net.*;
import java.io.*;
import java.util.*;

public class ClientTransmit{

    private String localHost = "127.0.0.1" ;
    private Socket socket = null;
    private ObjectOutputStream os = null;
    private ObjectInputStream is = null;

    public ClientTransmit(){}


    public ClientTransmit(String serverIP) 
    {
    if (!connectToServer(serverIP)) 
        {
       System.out.println("Cannot open socket connection...");            
    }
    }

    private boolean connectToServer(String serverIP) 
    {
    try  // open a new socket to port: 5050 and create streams
        {
       this.socket = new Socket(serverIP,5050);
       this.os = new ObjectOutputStream(this.socket.getOutputStream());
       this.is = new ObjectInputStream(this.socket.getInputStream());
       System.out.print("Connected to Server\n");
       return true;
    } 
        catch (Exception ex) 
        {
      System.out.print("Failed to Connect to Server\n" + ex.toString());    
      System.out.println(ex.toString());
      ex.printStackTrace();
      return false;
    }
 }

    private void getServerReply() 
    {
       System.out.println("In get server reply");
       String theReply; 
       theReply = (String) receive();
       if (theReply != null)
       {
      System.out.println(theReply);
       }
    }

    public void messageTransmit(Object o){

        Object obj = o;

        if(connectToServer(localHost)){

        if(obj instanceof FootballStream){
            FootballStream fs = (FootballStream) obj;
             try{            
                    System.out.println("About to transmit FootballStream object");
                    os.writeObject(fs);
                    os.flush();
                    this.getServerReply();
                 }

                 catch (Exception ex){ 
                   ex.printStackTrace();
                 }
        }           
        else if(obj instanceof MusicStream){
            MusicStream ms = (MusicStream) obj;         
             try{            
                    System.out.println("About to transmit MusicStream object");
                    os.writeObject(ms);
                    os.flush();
                    this.getServerReply();
                 }

                 catch (Exception ex){ 
                   ex.printStackTrace();
                 }
            }
         }

    }

    public void sendMessage(Vector<String> m) {
        String localhost = "127.0.0.1";
        String serverIP = localhost ;
        Vector<String> message = m;   

        if(connectToServer(serverIP)){
    try 
        {
        System.out.println("About to transmit shape");
        os.writeObject(message);
        os.flush();
        this.getServerReply();}

        catch (Exception ex) 
        {
       ex.printStackTrace();}
        }
    }


    private Object receive() 
    {
    Object o = null;
    try 
        {
       o = is.readObject();
    } 
        catch (Exception ex) 
        {
       System.out.println(ex.toString());
    }
    return o;
    }

}

1 个答案:

答案 0 :(得分:0)

看起来你每次都在messageTransmit中打开一个新的连接(通过调用connectToServer),但你永远不会关闭那个连接。我不确定这是否会导致您遇到阻塞,但这是您应该解决的问题。

要么保持连接打开并重新使用它,在这种情况下,你应该有一个checkConnection方法来检查当前连接是否仍然打开,如果没有,则打开一个;或者您希望每次都打开一个新连接,在这种情况下,您应该在完成从服务器接收响应后关闭连接。

对于阻塞,如果TCP连接的发送缓冲区已满,也会发生这种情况。如果OS发送缓冲区已满,则对os.writeObject和/或os.flush的调用可能会阻塞。要解除此问题,您应该使用NIO框架(例如Netty(或至少一个队列和单独的线程))来发送消息。您可能需要在服务器上验证它接收的数据,以查看是否导致阻止。