Help with first networking program - java

Here's the code.
public class testClient {
public static void main(String[] args) {
testClient abc = new testClient();
abc.go();
}
public void go() {
try {
Socket s = new Socket("127.0.0.1", 5000);
InputStreamReader sr = new InputStreamReader(s.getInputStream());
BufferedReader reader = new BufferedReader(sr);
String x = reader.readLine();
System.out.println(x);
reader.close();
} catch(IOException ex) {
ex.printStackTrace();
}
}
}
public class testServer {
public static void main(String[] args) {
testServer server = new testServer();
server.go();
}
public void go() {
try {
ServerSocket s = new ServerSocket(5000);
while(true) {
Socket sock = s.accept();
PrintWriter writer = new PrintWriter(sock.getOutputStream());
String toReturn = "No cake for you.";
writer.println(toReturn);
}
} catch(IOException ex) {
ex.printStackTrace();
}
}
}
java.io.* and java.net.* are imported in both classes.
Now, when I try to run these(using different terminals), nothing happens. What am I doing wrong?
Screen: http://i29.tinypic.com/250qlmt.jpg

When using PrintWriter you need to call flush method. Changed your code to following and it works :).
public class testServer {
public static void main(String[] args) {
testServer server = new testServer();
server.go();
}
public void go() {
try {
ServerSocket s = new ServerSocket(5000);
while(true) {
Socket sock = s.accept();
PrintWriter writer = new PrintWriter(sock.getOutputStream());
String toReturn = "No cake for you.";
writer.println(toReturn);
writer.flush();
}
} catch(IOException ex) {
ex.printStackTrace();
}
}
}

Your output is apparently buffered. After writing your output, try flushing:
writer.println(toReturn);
writer.flush();
Also, you may consider calling sock.close() in your server if you're done with the socket, otherwise the client will be left wondering what to do next.

Check out this simple working example.
import java.net.*;
import java.io.*;
public class Server {
Server() throws IOException {
ServerSocket server = new ServerSocket( 4711 );
while ( true ) {
Socket client = server.accept();
InputStream in = client.getInputStream();
OutputStream out = client.getOutputStream();
int multiplikator1 = in.read();
int multiplikator2 = in.read();
int resultat = multiplikator1 * multiplikator2;
out.write(resultat);
}
public static void main (String[] args) {
try {
Server server = new Server();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.net.*;
import java.io.*;
public class Client {
Client() throws IOException {
Socket server = new Socket ( "localhost", 4711 );
InputStream in = server.getInputStream();
OutputStream out = server.getOutputStream();
out.write( 4 );
out.write( 9 );
int result = in.read();
System.out.println( result );
server.close();
}
public static void main (String[] args) {
try {
Client client = new Client();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Close the writer.

Related

OutputStreamWriter and InputStreamReader for a Socket in Java, What am I doing wrong?

Using Sockets in java,
public class Server {
private static ServerSocket server;
private static int port = 9876;
static Socket p1 = null;
static Socket p2 = null;
public static void main(String args[]) throws IOException, ClassNotFoundException{
server = new ServerSocket(port);
Thread p1t = new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println("[Server] Waiting for connection");
p1 = server.accept();
System.out.println("[Server] Client connected");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(p1.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(p1.getInputStream()));
String msg = String.valueOf(in.readLine());
System.out.println(msg);
out.write(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
});
p1t.start();
}
}
and
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException, InterruptedException{
Socket socket = new Socket(InetAddress.getLocalHost().getHostName(), 9876);
if(socket.isConnected()) {
System.out.println("[Client] Connected");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
new Thread(new Runnable() {
#Override
public void run() {
while(true) {
try {
System.out.println(in.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
while(true) {
Scanner s = new Scanner(System.in);
out.write(s.nextLine());
}
}
}
}
The client is supposed to send a message to the server, and the server is supposed to relay that message back to the client; but either the BufferedReader for Client and Server are not reading anything that is sent, or the BufferedWriter for Client and Server is not sending anything.
I've also tried manually sending text using out.write("test"); in both classes.
What am I doing wrong in this situation?

How to enable multiple clients to communicate with the server?

The problem am having is that am not sure how to enable multiple clients to communicate with the server through threading, i've attempted it but I think am doing something wrong. Any help will be appreciated.
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
ArrayList clientOutputStreams;
public class ClientHandler implements Runnable {
BufferedReader reader;
Socket sock;
public ClientHandler(Socket clientSocket) {
try {
sock = clientSocket;
InputStreamReader isReader = new InputStreamReader(
sock.getInputStream());
reader = new BufferedReader(isReader);
} catch (Exception x) {
}
}
public void run() {
String message;
try {
while ((message = reader.readLine()) != null) {
System.out.println("read" + message);
tellEveryone(message);
}
} catch (Exception x) {
}
}
}
public void go() {
clientOutputStreams = new ArrayList();
try {
ServerSocket serverSock = new ServerSocket(5000);
while (true) {
Socket clientSocket = serverSock.accept();
PrintWriter writer = new PrintWriter(
clientSocket.getOutputStream());
clientOutputStreams.add(writer);
Thread t = new Thread(new ClientHandler(clientSocket));
t.start();
System.out.println("got a connection");
}
} catch (Exception x) {
}
}
public void tellEveryone(String message) {
Iterator it = clientOutputStreams.iterator();
while (it.hasNext()) {
try {
PrintWriter writer = (PrintWriter) it.next();
writer.println(message);
writer.flush();
} catch (Exception x) {
}
}
}
public static void main(String[] args) {
new ChatServer().go();
}`enter code here`
}
To allow multiple client to connect to your server you need a server to be continually looking for a new client to connect to. This can be done like:
while(true) {
Socket socket = Ssocket.accept();
[YourSocketClass] connection = new [YourSocketClass](socket);
Thread thread = new Thread(connection);
thread.start();
}
This is probably also best done in a separate server java file that can run independent of the client.

Handle more clients

Right now my server only can handle one client at a time. I am trying to use a Thread so that the server can handle several clients, but I am doing it wrong. I have added the thread in the try/catch clause where the serverSocket accepts the client, but this makes no difference. I don't get an error or anything, but it just doesn't work.
So what I want to do, is make the server not freeze at one client, but still accept several clients.
Here is the server code:
import java.io.*;
import java.net.*;
public class Server {
private BufferedReader reader;
private PrintWriter writer;
private int port;
public Server(int port)
{
this.port = port;
}
private String getSeverAddress() {
String host = null;
try {
InetAddress adr = InetAddress.getLocalHost();
host = adr.getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return host;
}
public void startServer() {
print("Contact this sever on address: " + getSeverAddress() + " port: " + port);
ServerSocket ss = null;
Socket socket = null;
Thread clientThread = null;
try {
ss = new ServerSocket(port);
socket = ss.accept();
clientThread = new Thread(new Client(socket));
clientThread.start();
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
String msg = null;
while (( msg = reader.readLine()) != null) {
print("System out: " + msg);
if(msg.equals("Bye")) {
print("Client left");
break;
}
}
ss.close();
socket.close();
reader.close();
writer.close();
} catch(SocketException e) {
e.printStackTrace();
} catch (IOException i ) {
i.printStackTrace();
return;
}
}
private void print(String msg) {
System.out.println(msg);
}
public static void main(String[] args) {
Server server = new Server(1111);
server.startServer();
}
}
Here is the client code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client implements Runnable{
private Socket client;
private BufferedReader reader;
private PrintWriter writer;
public Client(Socket socket)
{
client = socket;
try{
reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
writer = new PrintWriter(client.getOutputStream(), true);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
#Override
public void run() {
String msg = null;
BufferedReader r = null;
try {
r = new BufferedReader(new InputStreamReader(System.in));
} catch (Exception e1) {
e1.printStackTrace();
}
System.out.println("Write message to server");
while(true) {
try {
msg = r.readLine();
if(msg.equals("Quit") || msg == null) {
print("Disconnect");
break;
}
} catch (IOException e) {
e.printStackTrace();
}
writeToServer(msg);
}
try {
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void writeToServer(String msg) {
writer.println(msg);
}
private void print(String msg) {
System.out.println(msg);
}
public static void main(String[] args) {
Socket socket = null;
try {
socket = new Socket("localhost", 1111);
} catch (Exception e) {
e.printStackTrace();
}
Client client = new Client(socket);
client.run();
}
}
You are still trying to handle clients in your main thread. Main thread should just accept new connections and start new threads. You also have to do accept in a loop so multiple connections can be accepted:
ss = new ServerSocket(port);
while(true) {
Socket socket = ss.accept();
Thread clientThread = new Thread(new Runnable() {
public void run() {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
String msg = null;
while (( msg = reader.readLine()) != null) {
print("System out: " + msg);
if(msg.equals("Bye")) {
print("Client left");
break;
}
}
socket.close();
reader.close();
writer.close();
}});
clientThread.start();
}
You need to put your ss.accept() into a while loop and create a new Thread for every client accepted, which handles the connection.

Thread server/client stops after 2nd client joins

I have a server which uses multiple threads to accept multiple clients. I have it at the moment that when a client types something, it appears on the server as Client: text This works fine for 1 client. However the problem is when a second client joins.
They join fine and they can type fine. But the first client can only type 1 more thing then they stop, i.e their messages doesn't appear on the server. I presume they can do 1 as the method has been started but doesn't repeat. I've tried a while (true) loop (as seen in the code) and recalling the method at the end, neither work. I'm new to programming so don't have much expertise in this. Please find the code below :) (Note, indention is correct, just hasn't copied across properly)
Server:
package dod;
import java.net.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.io.*;
public class Server implements Runnable
{
PrintWriter out;
BufferedReader in;
Socket clientSocket;
ServerSocket serverSocket;
int portNumber;
AtomicInteger numClients = new AtomicInteger(0);
public static void main(String[] args)
{
Server s = new Server();
s.startup();
}
public void run()
{}
/**
* Start the server on the user picked port
*/
public void startup()
{
try
{
System.out.println("Enter a port");
Scanner dif = new Scanner(System.in);
portNumber = Integer.parseInt(dif.nextLine());
dif.close();
serverSocket = new ServerSocket(portNumber);
newThread();
}
catch (IOException e) {
System.out.println("Error");
System.exit(0);
}
}
public void newThread()
{
Thread thread =new Thread("C"+numClients.getAndIncrement())
{
public void run()
{
accept();
}
};
thread.start();
}
public void accept()
{
try
{
clientSocket = serverSocket.accept();
System.out.println("A new client has just connected.");
} catch(IOException e)
{
System.out.println("error");
System.exit(0);
}
newThread();
listenCommand();
}
public void listenCommand()
{
while (true)
{
try
{
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String userInput;
while ((userInput = in.readLine()) != null)
{
System.out.println("client: " + userInput);
}
} catch (IOException e)
{
System.out.println("Error");
System.exit(0);
}
}
}
}
Client:
package dod;
import java.io.*;
import java.net.*;
public class Client
{
public static void main(String[] args) throws IOException {
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);
try {
Socket serverSocket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(serverSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null)
{
out.println(userInput);
}
} catch(UnknownHostException e) {
System.out.println("error in host");
} catch(IOException e) {
System.out.println("error in IO");
}
}
}
Thank you! :)
*emphasized text*In the Server class you should have a Thread listening for new clients arriving and assigning them their own socket. You have the socket and the streams as a member variables, so everytime a new client comes you replace the socket. Also you open a new Thread for the accept connection, instead for the client itself.
Check the following (See that the client socket is another thread and I created a Runnable for it):
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;
public class Server
{
ServerSocket serverSocket;
int portNumber;
AtomicInteger numClients = new AtomicInteger(0);
public static void main(String[] args)
{
Server s = new Server();
s.startup();
}
/**
* Start the server on the user picked port
*/
public void startup()
{
try
{
System.out.println("Enter a port");
Scanner dif = new Scanner(System.in);
portNumber = Integer.parseInt(dif.nextLine());
dif.close();
serverSocket = new ServerSocket(portNumber);
newThread();
}
catch (IOException e) {
System.out.println("Error");
System.exit(0);
}
}
public void newThread()
{
Thread thread =new Thread("C"+numClients.getAndIncrement())
{
public void run()
{
while(true) {
try {
accept();
} catch (Exception e) {
// lof the exception
}
}
}
};
thread.start();
}
public void accept()
{
try
{
Socket clientSocket = serverSocket.accept();
new Thread(new ClientSocket(clientSocket)).start();
System.out.println("A new client has just connected.");
} catch(IOException e)
{
System.out.println("User disconnected");
System.exit(0);
}
}
class ClientSocket implements Runnable {
Socket clientSocket;
public ClientSocket(Socket clientSocket) {
this.clientSocket = clientSocket;
}
public void run() {
{
try
{
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String userInput;
while ((userInput = in.readLine()) != null)
{
System.out.println("client: " + userInput);
}
} catch (IOException e)
{
System.out.println("Error. Probably client disconnected");
// System.exit(0); do you want to exist when a client disconnects?
}
}
}
}
}

Sending bulk messages to all clients

I would like to know, how to send messages to all connected clients. To be more specific - to all ServerThreads.
Here are my classes:
public class Client {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
kkSocket = new Socket("127.0.0.1", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: localhost.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: localhost.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromUser, fromServer;
while (!(fromUser = stdIn.readLine()).equalsIgnoreCase("#quit")) {
out.println(fromUser);
fromServer = in.readLine();
System.out.println(fromServer);
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
Server: http://pastebin.com/ZpBydK58
ServerThread: http://pastebin.com/CwAM72c3
Assign each new ServerThread to a array. Then you can make a method in Server that loops through the ServerThread array and sends a message to each, and in ServerThread make a method to send a message.
Example:
public class Server {
public final static int maxClients = 10000;
public final static ServerThread[] clients = new ServerThread[maxClients];
public static int numOfClients = 0;
public static ServerSocket server;
public static void main(String[] args){
try{
server = new ServerSocket(4444);
while (numOfClients<maxClients){
clients[numOfClients+1] = new ServerThread(server.accept());
numOfClients++;
clients[numOfClients].start();
}
while (true){
server.accept().close();
}
}catch(Exception error){error.printStackTrace();}
}
public static void sendMessage(String message){
for (int i=0;i<numOfClients;i++){
clients[i].sendMessage(message);
}
}
}

Categories