简体   繁体   中英

Java network programming reading data from client

I'm newbie on the network programming. I want to make an simple server/client program in order to understand the basics of sockets. But unfortunately I can't understand one concept. Can I call readUTF() method before before client sends message? Because when I call second time this method my program crashes.

Error:

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)

Server:

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;
}

}

Client:

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!");
}
}

As the exception message states, the second call to readUTF is failing because the connection is being closed by the client. The code running the client currently follows the sequence of:

  1. Establish connection
  2. Setup input and output streams
  3. Read data from server
  4. Send data to server

After sending data to the server, there is no code left and no loop to repeat the process of sending/receiving, so the client closes its end of the connection and exits. You'll need to add a 5th step to your sequence:

  1. Establish connection
  2. Setup input and output streams
  3. Read data from server
  4. Send data to server
  5. Jump to 3 until a stopping condition is met

One approach to this sequence could be:

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() {
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM