Monte carlo server program - java

package montecarlo;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
*
* #author hafiz
*/
public class PICalcDistributedMaster {
ObjectOutputStream ostream;
ObjectInputStream istream;
Socket s;
String numThrows;
public void go(){
Scanner input = new Scanner(System.in);
System.out.println("Please enter number of throws: ");
numThrows = input.next();
int num = Integer.parseInt(numThrows);
try{
ServerSocket sock = new ServerSocket(100);
s = new Socket("127.0.0.1",100);
System.out.println("Waiting for connection");
System.out.println("Connection received from " + s.getInetAddress());
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("Sending Number");
pw.println(num);
ostream = new ObjectOutputStream(s.getOutputStream());
ostream.flush();
istream = new ObjectInputStream(s.getInputStream());
System.out.println("IO streams found");
istream.read(); //reads the input stream
}
catch (IOException ie){
ie.printStackTrace();
}
}
public static void main(String [] args){
PICalcDistributedMaster pim = new PICalcDistributedMaster();
pim.go();
}
}
i have adjusted the code to what you told me.I am still getting an error after running it more than once and i think it has to do with the garbage collector problem.My error is
java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:365)
at java.net.ServerSocket.bind(ServerSocket.java:319)
at java.net.ServerSocket.<init>(ServerSocket.java:185)
at java.net.ServerSocket.<init>(ServerSocket.java:97)
at montecarlo.PICalcDistributedMaster.go(PICalcDistributedMaster.java:31)
at montecarlo.PICalcDistributedMaster.main(PICalcDistributedMaster.java:56)
I assume the problem is with the socket it is binding to.I have tried different kinds but i cant still proceed

I'd like to suggest programming in smaller chunks. You've got a lot of code here and I don't think most of it ever runs:
ServerSocket sock = new ServerSocket(5000);
s = new Socket("127.0.0.1",5000);
s = sock.accept();
This code creates a server socket, binds it to a port.
Then you create a new socket s to connect to the server socket. (Which isn't yet listening.)
You destroy your new socket s with the sock.accept() result -- when you lose the last reference, the socket is free for garbage collection, and you only ever had one reference to it -- s.
The sock.accept() call probably ought to block until a new connection arrives. If it doesn't block, that means you triggered an exception even before all this code.
Incidentally, there's another instance of overwriting content nearly immediately after creating it:
String message = "connection successful";
message = (String) istream.readObject();
You'll never see connection successful from your program because you've overwritten the only reference you have to the string.
Probably the most egregious error in the entire program -- the one that is keeping you from making any real forward progress -- is that you throw away all the exception information:
try{
go(null);
}
catch(Exception e){
System.err.print("Connection terminated");
}
The catch(Exception e) { /* print message */ } means that you don't get any diagnostic information about what errors actually happened in your program. (Since you never use the parameter of go(), you should remove it completely and the needless null here, as well.)
One of these catch-all catch statements might be useful once you're confident that your product catches everything more specific, is nearly bullet-proof, and your customers demand an always-on reliable product. But it has no place in development -- you need to be alerted to faults in your programs with as much detail as possible so you can find and fix all your bugs.
Remove this. Get rid of your process() method completely -- it is only harmful.

Related

Client side is not sending message to server Java Socket

I am learning about sockets in java, but when I was running a program that sends messages from the client side to server side it doesn't show a message. If I enter some text on the client side it doesn't show up on the server side, but if I type endProcess it stops running. Which means that the message is going through it's just not showing up.
My Client.java code is here:
import java.net.*;
import java.io.*;
public class Client{
Socket soc;
DataInputStream dis;
DataOutputStream dos;
public Client(){
try{
soc = new Socket("(Address)",5000);
System.out.println("Connection Established");
dis = new DataInputStream(System.in);
dos = new DataOutputStream(soc.getOutputStream());
System.out.println("Streams connected");
}catch(UnknownHostException u){
System.out.println(u);
}catch(IOException i){
System.out.println(i);
}
String line = "";
while(!line.equals("endConnection")){
try{
line = dis.readUTF();
dos.writeUTF(line);
}catch(IOException i){
System.out.println(i);
}
}
try {
soc.close();
dis.close();
dos.close();
} catch (Exception e) {
System.out.println(e)
}
}
public static void main(String[] args) {
new Client();
}
}
Here is my Server.java code:
import java.net.*;
import java.io.*;
public class Server {
ServerSocket serSoc;
Socket soc;
DataInputStream dis;
public Server(){
try {
serSoc = new ServerSocket(5000);
System.out.println("Server Online");
soc = serSoc.accept();
System.out.println("Client Connected");
dis = new DataInputStream(new BufferedInputStream(soc.getInputStream()));
String line = "";
System.out.println("Waiting for input...");
while(!line.equals("endConnection")){
line = dis.readUTF();
System.out.println(line);
}
System.out.println("Client disconnected");
soc.close();
dis.close();
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
new Server();
}
}
There are many problems here.
Duplex protocol issues
line = dis.readUTF();
dos.writeUTF(line);
This isn't going to work; The dis.readUTF() line is going to block (freeze) until a line is read. The problem is, sometimes you have nothing to send in which case you want to read, and something you have nothing to read in which case you want to send. In practice you need to redesign this entirely; you need 2 threads. At which point you get into the issues of multicore, needing synchronization primitives and/or java.util.concurrent classes for all data that is shared between the 2 threads.
Alternatively, adopt a model that is strictly push or pull (where at any given time both parties already know who can send, and if the other party wants to send they simply cannot. For example, every party sends a simply 'NOTHING TO DO' message every second, trading places every time. This is quite an inefficient algorithm, of course. But could be written without involving multiple threads.
Flush and close issues
dos.writeUTF(line);
This doesn't actually send anything, or at least, isn't guaranteed to. To send any data on the internet, it gets wrapped in a packet which has lots of overhead. So, things are buffered until there's a full packet to send. Which means that line doesn't do anything. It just fills a buffer, no packets go out. You first need to close or flush. dos.flush() would help maybe. This is a big problem, because later you do:
soc.close();
dis.close();
dos.close();
You first close the socket, which, well, closes the socket. You then close the streams, which will also send anything that's still stuck in a buffer, except, that will fail, because the socket is already closed. In other words, the line you .writeUTF()-ed? It never gets there. You first shove it in a buffer, then you close the socket, then you send the buffer which won't work as the socket is already closed.
Broken error handling
} catch (Exception e) {
System.out.println(e);
}
Horrible. Don't do this. Your code reacts to any problem by printing something and just keeping right on going. That means if anything goes wrong, the client will start spamming an endless cavalcade of exception traces and locking up the system with any luck. You want the code to stop running when problems occur. Easiest way, by far, is to just stick throws IOException on your constructor and main method, which is allowed. Distant second best option is to configure your 'eh whatever' catch blocks as throw new RuntimeException("unhandled", e); instead of e.printStackTrace().
What you do (System.out.println(e);) is even worse - you are tossing away extremely useful information such as the stack trace and causal chain.

Java TCP Echo Server - Broadcast

I have a simple echo server, and I want when a connected user types anything to the server, all other clients and that client will get a the message + " | MOD".
It wont send to all clients now but it should and I just don't know what's wrong in my code, so now it will just send the message + " | MOD" to the client who sent the message but not to all others also as it should.
I just don't get it, I have a loop that goes through all clients, but it still won't send to all.
SERVER:
package com.murplyx.server;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
public static ServerSocket server;
public static ArrayList<Socket> clients = new ArrayList<Socket>();
public static void broadcast(String message) {
try {
for (Socket socket : clients) {
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println(message);
}
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
try {
server = new ServerSocket(9000);
while (true) {
clients.add(server.accept());
for (Socket socket : clients) {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = in.readLine();
if (line != null) {
broadcast(line + " | MOD");
}
}
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
CLIENT:
package com.murplyx.client;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client {
public static void main(String args[]) {
try {
while (true) {
Socket socket = new Socket("localhost", 9000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
out.println(input.readLine());
System.out.println(in.readLine());
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Please help.
Thanks alot.
One of the issues you have is that each client will repeatedly do read stdin, write socket, read socket, write stdout, ... ad infinitum.
When you broadcast all other clients are still typically sat in the read stdin phase, so they don't know that there's stuff waiting to be read on the socket. They're still waiting for the user to enter something.
One of the simplest options is to start two threads in each client - one just handles read stdin, write socket, ... and the other handles read socket, write stdout.
[Another (potentially more sophisticated) option us to use Java NIO to poll both the socket and stdin for available input at the same time].
A second issue is that you're blocking in the accept call in the server, and then reading from each socket in turn. You might accept in one thread, and have another thread per client read from just the client, and rebroadcast to the others. NIO can also be a good option here - you can poll for reads any any client.
I'm not exactly sure how ArrayLists play with sockets, so I definitely would go back to using a normal array for it (see the edited code here Java EchoTCPServer - Send to all clients)
Some things I see that I think can to be fixed:
On the Client:
-Stop closing the socket in the While loop. Close it OUTSIDE the while loop (When the client is done with the server). Also, declare the socket outside the Loop.
NOTE ON THIS: When a client makes a socket to connect to the server, it is automatically given a device port, so two different devices will never have the same IP connected to the server. A TCP connection consists of 2 ports, server socket and client socket, and the sockets are denoted by [deviceip:port,serverip:port] (iirc).
-Also, on the client you don't need to declare a new reader everytime you move through the while loop. Put that all outside. The only thing inside the while loop should be your readline + print statements.
-readLine is a blocking method. (just in case you don't know what that means, it means that readLine will make your program be stuck there until the it actually reads a line. To bypass this, you can use an if statement combined with the .ready() function. The ready function checks to see if there is anything to be "read in", so if there's no input it wont be stuck on "readLine".
On the Server:
-Like i said earlier, I'd change back to using a normal Array.
-Your server will still get stuck on .accept(). As such, you will never be able to read input from the clients except once after each connection. You can use a thread to listen instead, and it will still work.
eg: (this code goes with the code that's in the link i attached (also your question), put it before the while loop of your server)
// create a tcp listener thread to deal with listening to clients
Thread listenerThread = new Thread() {
public void run() {
String clientSentence;
while (true) {
//loop through each connected socket
for (int i = 0; i <= intLastSocket; i++) {
Socket z = clientSocket[i];
//make sure the socket is not null or closed (can't do anything
//with closed or null sockets
if ((z != null) && (!z.isClosed())) {
try {
// Deal with TCP input here
BufferedReader input = new BufferedReader(new
InputStreamReader(z.getInputStream()));
// read in a line but only if there is one
if (input.ready()) {
clientSentence = input.readLine();
}
} catch (IOException x) {
printTCP("IOException caught when reading in: "
+ x.toString());
}
if (clientSentence != null) {
System.out.println("Received from client: "
+ clientSentence);
//send this message to the client
outputStream[i].println(clientSentence + " | MOD");
}
// clear the input
clientSentence = null;
}
}
}
}
};
listenerThread.start();

Java Socket Chat Not Displaying All Messages

I am trying to work through a socket chat with just one client and the server. I have it successfully running, as in the server is capable of passing messages back and forth, but when I attempt to make the server side implementation a bit more complex, adding commands and such, that the client can use, the communication fails. It appears it might go out of sync even as using the same commands over and over again can produce different results, even though I flush everything after every command.
Example of simplistic output, this works as expected, every time:
Client:
import java.io.*;
import java.net.*;
public class Test1Client
{
public static void main(String args[])
{
InputStreamReader convert = new InputStreamReader(System.in);
BufferedReader stdin = new BufferedReader(convert);
try
{
Socket echoClient = new Socket("localhost", 17);
PrintStream outs = new PrintStream(echoClient.getOutputStream());
BufferedReader ins = new BufferedReader(new InputStreamReader(echoClient.getInputStream()));
while(true){
System.out.print("Type whatever you want: ");
String line = stdin.readLine();
outs.println(line);
System.out.println("Server says: " + ins.readLine());
}
}
catch (IOException e)
{
System.out.println(e);
}
}
}
Server:
import java.net.*;
import java.util.ArrayList;
import java.io.*;
public class Test1Server
{
public static void main(String args[])
{
try
{
ServerSocket socket= new ServerSocket(12167);
//Try not to use port number < 2000.
System.out.println("Waiting for a client to connect...");
Socket s = socket.accept();
System.out.println("Client Connected.");
BufferedReader ins = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintStream outs = new PrintStream(s.getOutputStream());
while (true)
{
String line = ins.readLine();
outs.println(line);
}
}
catch (IOException e)
{
e.getStackTrace();
}
}
}
I get output like this, it works every time just spitting it back out:
Type whatever you want: login
Server says: login
Type whatever you want: login
Server says: login
Type whatever you want: login
Server says: login
Type whatever you want: login
Server says: login
But when I make the server side a bit more complex by replacing its while(true) block with the following, I get a much more messy result:
String line = ins.readLine();
String response = manager.process(line);
outs.println(response);
outs.flush();
process:
msg= "User logged in successfully \n";
return msg;
You'll also notice some commented lines in the process command code. When I give back a simple message the server seems to keep up, but when I use the login function as well it gives the terrible output like this:
Type whatever you want: login ryanne
Server says: ryanne logged in successfully
Type whatever you want: login ryanne
Server says:
Type whatever you want: login ryanne
Server says: You may already be logged in or did not use correct username or password
Type whatever you want: login ryanne
Server says:
Type whatever you want: newuser jeff
Server says: You may already be logged in or did not use correct username or password
Type whatever you want: newuser jeff 12345
Server says:
Type whatever you want: new user jeff 12345
Server says: You may already be logged in or did not use correct username or password
Type whatever you want:
Again, notice the blanks where nothing comes back from the server, and then even the change in the commands does not prompt different responses. Its as if it went out of sync, just by using one additional function?
You have some "\n" at the end of some strings.
If you both put "\n" and use println, you will have double carriage returns, which will mess up your protocol. Remove the "\n"'s, and it should work better.
Maybe, data you sent was not flushed. Use outs.flush(); after outs.println(line); or change it's constructor call to PrintStream(echoClient.getOutputStream(),true); (enable auto-flush on printing new line)

Java Heap Memory error from socket

I am trying to open a socket and listen. Clients written in PHP will then send XML requests. At the moment I am just send the string "test" to it and I am getting a Memory Heap Error.
Here is my java code for the server:
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class main {
/**
* #param args
*/
public static void main(String[] args) {
server();
}
public static void server() {
ServerSocket MyService = null;
try {
MyService = new ServerSocket(3030);
}
catch (IOException e) {
System.out.println(e);
}
Socket serviceSocket = null;
try {
serviceSocket = MyService.accept();
}
catch (IOException e) {
System.out.println(e);
}
DataInputStream in;
try {
in = new DataInputStream(serviceSocket.getInputStream());
System.out.println("DEV STEP 1");
int len = in.readInt();
System.out.println(len);
byte[] xml = new byte[len];
in.read(xml, 0, len);
//System.out.print(xml.toString());
//Document doc = builder.parse(new ByteArrayInputStream(xml));
}
catch (IOException e) {
System.out.println(e);
}
}
}
The error I am getting is:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at main.server(main.java:39)
at main.main(main.java:12)
I have done a search and there are plenty of explanations of this error on here, however I can not work out why when I am sending a 4 letter String len is 1952805748.
Well you are getting the out of memory error because the len is so huge. If you are sending the data as characters and then doing a readInt() on it, then that's what's causing your problem. You need to read the data as characters.
Your numeric valid is probably the binary for the string "test". You should just read a string from the InputStream, not sure why you need a DataInputStream as that's something that supports reading binary, etc, which is not what you are doing. Just use a BufferedInputStream and then do a normal read on it.
To expand on Francis Upton's answer, you are getting a heap exception because you are trying to read n bytes from the incoming socket stream, where n represents the totally arbitrary integer you read at the beginning of your processing loop. And the reason I call it totally arbitrary is because you never actually sent a separate int in your client code. So your code is simply reading an int from whatever is in the first 4 bytes of the input stream, which could be anything at all.
Take a look at IOUtils in Apache Commons IO, it contains nice methods for reading an entire data stream in one shot (toByteArray, toString, etc).

Java ObjectInputStream hanging

I am feeling really stupid right now guys.... basically I am connecting over TCP on a local machine... and when I try to make the In/out streams at the client it wont get passed creating the object input stream. What gives? This stops after printing 2... no exceptions or anything... This isn't the first time I've used this class which is partialy why I am puzzled.
try {
System.out.println("1");
mySocket = new Socket("localhost", 11311);
System.out.println("12");
oos = new ObjectOutputStream(mySocket.getOutputStream());
System.out.println("2");
ois = new ObjectInputStream(mySocket.getInputStream());
System.out.println("13");
} catch (Exception e) {
e.printStackTrace();
}
From the specification of ObjectInputStream:
This constructor will block until the corresponding ObjectOutputStream
has written and flushed the header.
(For future readers:) I had the same problem because i made a silly change in server program and didn't test it for a long time then i was confused about why program is locked.
ServerSocket accepts the connection (responderSocket = serverSock.accept();) then suddenly for a inapropriate if (The silly change i mentioned!) program jumps out of the thread and because i didn't add a finally block to close streams and sockets the socket was left abandoned w/o sending or recieving anything (even stream headers). So in client side program there was no stream header (When i debbugged The code i saw that the last function executed before lock was:
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
enableOverride = false;
readStreamHeader(); //// <== This function
bin.setBlockDataMode(true);
}
readStreamHeader();)
So be careful about what happens in server side, maybe problem isn't where you expecting it!

Categories