Java Sockets: My server input stream will not read from the client output stream?

11,378

The problem with your code is not the "sockets" its your communication protocol. You are effectively closing the socket before the server has a chance to write out "hi".

To debug this, you want to reduce the complexity of your program. There are a number of things that don't make any sense or matter in your program.

So, a little background on Sockets. There are two types of sockets. A "ServerSocket" and a "Socket" The ServerSocket is sort of like a secretary. Its only job is to listen for calls and then pass them on. This is what the "accept" does. Before any client connects, the accept() will block until it receives a connection. Once the client connects, the accept returns a Socket representing the connection.

The regular Socket is where all the work occurs. You can think of it as a telephone connection. You can talk to someone remotely with the OutputStream, and listen using the InputStream. The challenge is that you need to create some sort of communication (called a protocol) for your two sockets to communicate.

You need to figure out how you want to delimit your commands. You could pass a fixed length number and then the data if you want a "length" delimited protocol or you could use a special character for the end of the message (what you currently have). For the quick and dirty, I often use the latter with a newline character. The easiest is to just use a PrintWriter for writing and a Scanner for reading.

The next step is to figure out the communication pattern for the client and the server. Think if it as passing a ball back and forth. If the client says something, the other side should be listening (and vice versa).

Once the protocol and logic is figured out, you can then move the logic for "handling" the server side into separate threads (called a worker pattern) so that the server can handle more than one client at a time. If you want to go even further, you can implement a reactor with a thread pool so that the server doesn't run out of threads, but that is probably for another day/question.

I would recommend following the Java tutorial on Sockets: http://docs.oracle.com/javase/tutorial/networking/sockets/index.html

Share:
11,378
MrDrProfessorTyler
Author by

MrDrProfessorTyler

Updated on June 04, 2022

Comments

  • MrDrProfessorTyler
    MrDrProfessorTyler almost 2 years

    EDIT: Ik it is long but does anyone know how to program sockets??

    My problem is confusing me a bit. I have a server running on one computer and on another, I have a client connected to it. When I type a message from the client into the console and send it, the server does not seem to receive it. Anybody know why because I have been testing with printing to the console for the last 3 hours and cannot figure this out. I am relatively new to sockets so don't be too harsh if I am just being an idiot.

    Heres my code for the client side:

    import java.net.*;
    import java.util.Scanner;
    import java.io.*;
    
    public class SocketClient {
    
    public static void main(String [] args) {
        String host = "************";
        int port = 25565;
    
        StringBuffer instr = new StringBuffer();
        String TimeStamp;
        System.out.println("SocketClient initialized");
    
        try {
            InetAddress address = InetAddress.getByName(host);
            Socket connection = new Socket(address, port);
    
            BufferedOutputStream bos = new     BufferedOutputStream(connection.getOutputStream());
            OutputStreamWriter osw = new OutputStreamWriter(bos, "US-ASCII");
    
            Scanner scan = new Scanner(System.in);
            String message = scan.nextLine();
    
            TimeStamp = new java.util.Date().toString();
            String process = "Server called on " + host + ":" + port + " at " + TimeStamp + ": " + message + (char) 13;
    
            osw.write(process);
            osw.flush();
    
            BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
    
            InputStreamReader isr = new InputStreamReader(bis, "US-ASCII");
    
            int c;
            while ( (c = isr.read()) != 13)
                instr.append( (char) c);
    
            connection.close();
            System.out.println(instr);
    
        } catch (UnknownHostException e) {
            System.err.println("UnknownHostException: " + e);
        } catch (IOException e) {
            System.err.println("IOExcepion: " + e);
        }
    }
    }
    

    Here is the code to connect the client to the server:

    import java.io.IOException;
    import java.net.*;
    
    public class MultipleSocketServer {
    
    public static Socket connection;
    public static String name = "Tyler's Server";
    public static int limit = 2;
    public static Thread[] clients = new Thread[limit];
    public static int current = 0;
    public static int port = 25565;
    public static String[] connected = {"", ""};
    public static ServerSocket socket;
    
    public static void main(String[] args) {
        System.out.println("Server starting...");
        try {
            ServerSocket socket = new ServerSocket(port);
            while(true) {
                Socket connection = socket.accept();
                String ip = connection.getRemoteSocketAddress().toString().substring(1, 13);
                loop:
                for(int i = 0; i < connected.length; i++) {
                    if(connected[0].equals(ip) || connected[1].equals(ip)) {
                        break loop;
                    }else if(!connected[i].equals(ip)) {
                        connected[i] = ip;
                        System.out.println(ip);
                        MultiServer_Client client = new     MultiServer_Client(connection, i);
                        Thread run = new Thread(client);
                        run.start();
                        break loop;
                    }
                }
            }
        } catch (IOException e1) {
            System.out.println("Could not bind server on: " + port);
            System.exit(-1);
        }
    }
    }
    

    And here is my code to handle each client as connected:

    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.Socket;
    
    public class MultiServer_Client implements Runnable {
    
    public String time;
    public Socket client;
    public StringBuffer process = new StringBuffer();
    
    public BufferedInputStream inputStream;
    public InputStreamReader reader;
    
    public BufferedOutputStream outputStream;
    public OutputStreamWriter writer;
    
    public boolean connected = true;
    
    public int ID;
    
    public MultiServer_Client(Socket connection, int i) {
        client = connection;
        ID = i;
        try {
            inputStream = new BufferedInputStream(client.getInputStream());
            reader = new InputStreamReader(inputStream);
    
            outputStream = new BufferedOutputStream(client.getOutputStream());
            writer = new OutputStreamWriter(outputStream, "US-ASCII");
        } catch (IOException e) {
            System.out.println("IOException: " + e);
        }
        System.out.println("Client connected...");
        write("Connected to " + MultipleSocketServer.name);
    }
    
    public void run() {
        while(connected) {
            write("hi");
        }
        System.out.println("Disconnecting client...");
    }
    
    public void write(String authen) {
        try {
            time = new java.util.Date().toString();
            String message = time + ": " + authen + (char) 13;
            writer.write(message);
            writer.flush();
        } catch (IOException e) {
            connected = false;
            MultipleSocketServer.connected[ID] = "";
        }
    }
    
    public void read() {
        //read from client
        int character;
        process = new StringBuffer();
        try {
            while ((character = reader.read()) != 13) {
                process.append((char) character);
            }
            System.out.println(process);
            process.delete(0, process.length());
        } catch (IOException e) {
            connected = false;
            MultipleSocketServer.connected[ID] = "";
        }
    }
    }
    

    Srry if I cannot help very much. As I said, I am new to sockets and no one else seems to have any problems with this... Thanks :)