【发布时间】:2015-01-08 17:01:24
【问题描述】:
好像连接第二个客户端后连接被重置了
这是第一个客户,我已经评论了大部分内容以使更清晰
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class ClientOneGui extends JFrame {
private static final long serialVersionUID = 1L;
JTextField userInput = new JTextField();
JTextArea chatHistory = new JTextArea();
Socket cS; // Socket to connect to Server
ObjectOutputStream output; // To send messages to server, server sends to clientTwo(another client)
ObjectInputStream input; // To receive messages from server, message sent to server from clientTwo(another client)
String message;// Variable to hold messages sent from server, which is from another client
//Constructor
public ClientOneGui() {
super("ClientOne"); //Window Title
add(userInput, BorderLayout.SOUTH); // add TextField for user input
add(chatHistory); // add TextArea for chat history
// Detects enter pressed by user inside the TextField
// then run the SendMessage method
userInput.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
SendMessage(e.getActionCommand());
userInput.setText("");
}
}
);
//Housekeeping stuff
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setLocationRelativeTo(null);
this.setSize(300, 400);
}
//This is the only method called in the main class, after the constructor
//this method runs the other three methods inside it
public void StartClient() {
ConnectToServer();
SetupStreams();
ReceiveMessage();
}
//Connect to server
public void ConnectToServer() {
try{
appendString("Waiting for connection"); // appendString method is created down below
cS = new Socket("127.0.0.1",45678);
appendString("Connected to server!");
} catch(IOException e) {
System.out.println("ConnectToServer method");
}
}
//Setup output and input streams
public void SetupStreams() {
try {
output = new ObjectOutputStream(cS.getOutputStream());
output.flush();
input = new ObjectInputStream(cS.getInputStream());
appendString("Start chatting!");
} catch (IOException e) {
System.out.println("SetupStreams ClientOne Method");
}
}
//Send message when enter is pressed
public void SendMessage(String str) {
try {
output.writeObject(str); // Write message to server
appendString(str);
} catch (IOException e) {
System.out.println("SendMessage ClientOne Method");
}
}
//Keep receiving message while connected
public void ReceiveMessage() {
do{
try {
message = (String) input.readObject(); // Read the message from server
appendString(message);
} catch (IOException | ClassNotFoundException e) {
System.out.println("Client One connection lost");
}
}while(cS.isConnected());
}
//Add text to chatHistory
public void appendString(final String string) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
chatHistory.append(">"+string+"\n");
}
});
}
}
这是第二个客户端,98% 与第一个相同
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class ClientTwoGui extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
JTextField userInput = new JTextField();
JTextArea chatHistory = new JTextArea();
Socket cS; // Socket to connect to Server
ObjectOutputStream output; // To send messages to server, server sends to clientOne(another client)
ObjectInputStream input; // To receive messages from server, message sent to server from clientOne(another client)
String message; // Variable to hold messages sent from server, which is from another client
//Constructor
public ClientTwoGui() {
super("ClientTwo"); //Window Title
add(userInput, BorderLayout.SOUTH); // add TextField for user input
add(chatHistory); // add TextArea for chat history
// Detects enter pressed by user inside the TextField
// then run the SendMessage method
userInput.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
SendMessage(e.getActionCommand());
userInput.setText("");
}
}
);
//Housekeeping stuff
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setLocationRelativeTo(null);
this.setSize(300, 400);
}
//This is the only method called in the main class, after the constructor
//this method runs the other three methods inside it
public void StartClient() {
ConnectToServer();
SetupStreams();
ReceiveMessage();
}
//Connect to server
public void ConnectToServer() {
try{
appendString("Waiting for connection");
cS = new Socket("127.0.0.1",45678);
appendString("Connected to server!");
} catch(IOException e) {
e.printStackTrace();
}
}
//Setup output and input streams
public void SetupStreams() {
try {
output = new ObjectOutputStream(cS.getOutputStream());
output.flush();
input = new ObjectInputStream(cS.getInputStream());
appendString("Start chatting!");
} catch (IOException e) {
System.out.println("SetupStreams ClientTwo Method");
}
}
//Send message when enter is pressed
public void SendMessage(String str) {
try {
output.writeObject(str); // Write message to server
appendString(str);
} catch (IOException e) {
System.out.println("SendMessage ClientTwo Method");
}
}
//Keep receiving message while connected
public void ReceiveMessage() {
do{
try {
message = (String) input.readObject(); // Read the message from server
appendString(message);
} catch (IOException | ClassNotFoundException e) {
//=====================================================================================
System.out.println("Client Two connection lost"); // <<<<<Error
//=====================================================================================
}
}while(cS.isConnected());
}
//Append string to chatHistory
public void appendString(final String string) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
chatHistory.append(">"+string+"\n");
}
});
}
}
这是服务器端,位于两个客户端之间,发送和接收消息
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TheServer {
//One server socket, two client sockets
ServerSocket sS;
Socket cSOne;
Socket cSTwo;
//The streams
ObjectOutputStream outputOne; //input Stream for first client
ObjectInputStream inputOne; //output Stream for first client
ObjectOutputStream outputTwo; //input Stream for second client
ObjectInputStream inputTwo;//output Stream for second client
//The messages
String messageOne; // messages from client one
String messageTwo; // messages from client two
//This is the only method called
public void StartServer() {
System.out.println("Server Started");
try {
sS = new ServerSocket(45678);
WaitForClient();
SetupStreams();
} catch (IOException e) {
System.out.println("StartServer Method " + e);
}
}
//Connect to client
public void WaitForClient() {
try{
cSOne = sS.accept();
System.out.println("Connected to client one");
cSTwo = sS.accept();
System.out.println("Connected to client Two");
} catch(IOException e) {
System.out.println("WaitForClient Method");
}
}
//Setup output and input streams
public void SetupStreams() {
try {
outputOne = new ObjectOutputStream(cSOne.getOutputStream());
outputOne.flush();
inputOne = new ObjectInputStream(cSOne.getInputStream());
System.out.println("Client One streams setup");
outputTwo = new ObjectOutputStream(cSTwo.getOutputStream());
outputTwo.flush();
inputTwo = new ObjectInputStream(cSTwo.getInputStream());
System.out.println("Client Two streams setup");
} catch (IOException e) {
System.out.println("SetupStreams Method");
}
}
//Keep receiving messages while both clients are connected
public void ReceiveMessage() {
do{
try {
messageOne = (String)inputOne.readObject();
messageTwo = (String)inputTwo.readObject();
outputTwo.writeObject(messageOne);
System.out.println(messageOne);
outputOne.writeObject(messageTwo);
System.out.println(messageTwo);
} catch (ClassNotFoundException | IOException e) {
System.out.println("SendReceiveMessage Method " + e);
}
}while(!messageOne.equals(null)||!messageTwo.equals(null));
}
//Keep sending messages while both clients are connected
public void SendMessage() {
do{
try {
outputTwo.writeObject(messageOne);
System.out.println(messageOne);
outputOne.writeObject(messageTwo);
System.out.println(messageTwo);
} catch (IOException e) {
System.out.println("SendReceiveMessage Method " + e);
}
}while(!messageOne.equals(null)||!messageTwo.equals(null));
}
}
据我了解,在两个客户端都连接后,连接并没有保持活动状态,我已经读到连接不应该在被告知之前关闭。我不知道是什么让它自己关闭了。
我收到的错误是在客户端两个代码的第 101 行,这意味着在创建流后连接已关闭。
public class ServerMain {
public static void main(String[] args) {
TheServer sc = new TheServer);
sc.StartServer();
}
}
【问题讨论】:
-
请发布服务器主方法,可能服务器在客户端传输数据之前终止。
-
@rafalopez79 完成编辑
标签: java input stream output serversocket