我通过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;
}
}
答案 0 :(得分:0)
看起来你每次都在messageTransmit中打开一个新的连接(通过调用connectToServer),但你永远不会关闭那个连接。我不确定这是否会导致您遇到阻塞,但这是您应该解决的问题。
要么保持连接打开并重新使用它,在这种情况下,你应该有一个checkConnection方法来检查当前连接是否仍然打开,如果没有,则打开一个;或者您希望每次都打开一个新连接,在这种情况下,您应该在完成从服务器接收响应后关闭连接。
对于阻塞,如果TCP连接的发送缓冲区已满,也会发生这种情况。如果OS发送缓冲区已满,则对os.writeObject和/或os.flush的调用可能会阻塞。要解除此问题,您应该使用NIO框架(例如Netty(或至少一个队列和单独的线程))来发送消息。您可能需要在服务器上验证它接收的数据,以查看是否导致阻止。