4

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 :)

6
  • 1
    You seem to be disconnecting silently whenever an exception occurs without logging the exception itself. Could it be possible that an exception is occurring in your code due to which the server is disconnecting the client? Commented Jan 30, 2012 at 2:12
  • Well in my write() and read() methods in the server, if the code fired an exception, the server would exit as it does when I close my client. I am also printing out everything in my client class when there is an exception of any sort. I am really stumped here hahaha. Thanks for the advice though. Commented Jan 30, 2012 at 2:18
  • Also, whenever I loop the socket.accept() to connect the client to the server, the read() and write() work just fine and the connection works perfectly but it doesn't allow me to track different clients and a computer can have an infinite amount of clients running on the server. No way to fix? Commented Jan 30, 2012 at 2:25
  • Your write method is throwing a "Broken Pipe" SocketException. Your server is not shutting down because it is catching it with the IOException. Add a e.printStackTrace(); to see it. Commented Jan 30, 2012 at 2:25
  • It wont catch anything when I call write()? It runs through completely but the client wont respond and the read() gets stuck at the while() loop Commented Jan 30, 2012 at 2:29

1 Answer 1

6

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks I managed to fix the code up a bit and make it more efficient. I figured out there was a big problem on the client side though. It seems as though I was continuously reconnecting to the server whenever I wrote and read the strings. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.