我是网络编程的新手。我想制作一个简单的服务器/客户端程序,以了解套接字的基础知识。但不幸的是,我无法理解一个概念。我可以在客户端发送消息之前调用readUTF()
方法吗?因为当我第二次调用这个方法时,我的程序崩溃了。
错误:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at Messaging.ServerSideConnection.receiveData(ServerSideConnection.java:59)
at Messaging.Server.printInputs(Server.java:88)
at Messaging.Server$2.run(Server.java:35)
at java.lang.Thread.run(Unknown Source)
服务器:
package Messaging;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
private static final String configId = "SERVER_CONFİG_ID_";
private static final int port = 6066;
private volatile ArrayList<ServerSideConnection> connections;
public static void main(String[] args){
new Server();
}
public Server(){
connections = new ArrayList<>();
Thread acceptConnections = new Thread(new Runnable(){
public void run() {
try {
acceptConnections(port);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Thread printInputs = new Thread(new Runnable(){
public void run() {
while(true){
printInputs();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
acceptConnections.start();
printInputs.start();
try {
acceptConnections.join();
printInputs.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void acceptConnections(int port) throws IOException{
ServerSocket serverSocket = new ServerSocket(port);
while(true){
System.out.println("SERVER : Listening..");
ServerSideConnection connection = new ServerSideConnection(serverSocket.accept());
connection.sendData(configId + Integer.toString(connection.getId()));
connections.add(connection);
System.out.println("SERVER : Connected to " + connection.getSocket().getInetAddress());
}
}
public void controlConnectionLife(){
int instantSize = connections.size();
for(int i=0;i<instantSize;i++){
if(!connections.get(i).isConnected()){
connections.get(i).killConnection();
connections.remove(i);
i--;
}
}
}
public void printInputs(){
for (ServerSideConnection connection : connections){
System.out.println(connection.isConnected());
try {
System.out.println(connection.receiveData());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ServerSideConnection {
private static int count;
private int id;
private Socket socket;
private DataInputStream input;
private DataOutputStream output;
public ServerSideConnection(Socket socket){
this.socket = socket;
initOutputStream();
initInputStream();
count++;
id = count;
}
private void initInputStream(){
try {
InputStream in = socket.getInputStream();
input = new DataInputStream(in);
} catch (IOException e) {
e.printStackTrace();
}
}
private void initOutputStream(){
try {
output = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void killConnection(){
try {
output.close();
input.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public String receiveData() throws IOException{
return input.readUTF();
}
public void sendData(String msg) throws IOException{
output.writeUTF(msg);
output.flush();
}
public boolean isConnected(){
return socket.isConnected();
}
public int getId(){
return id;
}
public Socket getSocket(){
return socket;
}
public DataInputStream getInput() {
return input;
}
public DataOutputStream getOutput() {
return output;
}
}
客户端:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class ClientSideConnection {
private static final String configId = "SERVER_CONFİG_ID_";
private static final int port = 6066;
private static final String host = "localhost";
private int id;
private Socket socket;
private DataInputStream input;
private DataOutputStream output;
public static void main(String[] args){
try {
new ClientSideConnection(port,host);
} catch (IOException e) {
e.printStackTrace();
}
}
public ClientSideConnection(int port, String host) throws UnknownHostException, IOException{
boolean connected = false;
while(!connected){
try{
socket = new Socket(host,port);
connected = true;
System.out.println("CLIENT : Connected to " + socket.getInetAddress());
}
catch(ConnectException e){
connected = false;
}
}
initOutputStream();
initInputStream();
String receivedId = receiveData();
if(receivedId.substring(0, 17).equals(configId))
id = Integer.parseInt(receivedId.substring(17,receivedId.length()));
sendTestData();
}
private void initInputStream(){
try {
input = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
private void initOutputStream(){
try {
output = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void killConnection(){
try {
output.close();
input.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public String receiveData() throws IOException{
return input.readUTF();
}
public void sendData(String msg) throws IOException{
output.writeUTF(msg);
output.flush();
}
public int getId() {
return id;
}
public void sendTestData(){
Scanner scan = new Scanner(System.in);
System.out.print("enter test msg: ");
String msg = scan.nextLine();
try {
sendData(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("msg sended!");
}
}
答案 0 :(得分:2)
正如异常消息所述,对readUTF
的第二次调用失败,因为客户端正在关闭连接。运行客户端的代码目前遵循以下序列:
将数据发送到服务器后,没有代码,也没有循环重复发送/接收过程,因此客户端关闭其连接结束并退出。您需要在序列中添加第5步:
此序列的一种方法可能是:
public class Client {
public static void main(String[] args) {
Client client = new Client();
boolean sucessful;
do {
String data = client.receiveData();
successful = client.sendData(data);
} while(successful);
client.close();
}
public Client() {
//setup connection and in/output streams
}
public String receiveData() {
//read from input
}
public boolean sendData(String data) {
//send data
}
public void close() {
}
}