Simple Client Server program - java

I making an elementary project based on TCP/IP where server listens to the client and then provides a capital sentence of the incoming data.
Server.java:
import java.io.*;
import java.net.*;
public class Server
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(7948);
Socket s= ss.accept();
System.out.print("Server connected\n");
BufferedInputStream bis = new BufferedInputStream (s.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream (s.getOutputStream());
while(true)
{
int a = bis.available();
byte b[] = new byte[a];
bis.read(b);
String str = new String(b);
str = str.toUpperCase();
b = str.getBytes();
bos.write(b,0,b.length);
bos.flush();
if(str.equals("BYE"))
break;
else
continue;
}
System.out.print("\nServer Disconnecting");
String str = "Adios Amigo";
bos.write(str.getBytes());
bos.flush();
bis.close();
bos.close();
ss.close();
s.close();
}
}
Client.java:
import java.io.*;
import java.net.*;
public class Client
{
public static void main(String[] args) throws Exception
{
BufferedReader clientStream = new BufferedReader(new InputStreamReader(System.in));
String str;
int a;
byte[] b;
Socket s = new Socket(InetAddress.getLocalHost(), 7948);
BufferedOutputStream bos = new BufferedOutputStream (s.getOutputStream());
BufferedInputStream bis = new BufferedInputStream (s.getInputStream());
one:while(true)
{
str = clientStream.readLine();
b =str.getBytes();
bos.write(b);
bos.flush();
a=bis.available();
b = new byte[a];
bis.read(b);
str = new String (b);
str.trim();
System.out.print("The server says: "+str);
if (str.equals("BYE"))
{
bis.read(b);
str = new String (b);
System.out.print("The server says: "+str);
break one;
}
}
s.close();
clientStream.close();
bos.close();
bis.close();
}
}
The program is working properly except for one problem, output at client side comes after two inputs. It means that I have to give two inputs from client sides to get the first output, and this continues. I am unable to track the bug.
Can anyone please help ?

in the client, you send data to the server, and then immediately call a.available() - this function does not wait for data to be sent from the server. since the server is unlikely to have responded with data by the time the .available() is called, the function returns zero.
because of this, your byte array b (please use more descriptive variable names in the future) is of length zero.
once the array of size zero is created, you finally wait for data by calling bis.read() - .read() is a blocking call. it will wait for data from the server. this data is not actually read, because the array you are reading in to is size zero. this results in the printing out of an empty string.
the following code will fix the problem, but for the future, i do not recommend using .available() - it is rather unreliable in my experience. you should check if data is available by simplying attempting to read data.
Client.java:
one:while(true)
{
str = clientStream.readLine();
b =str.getBytes();
bos.write(b);
bos.flush();
while (bis.available() <= 0)
{
// wait for data!
}
a=bis.available();
b = new byte[a];
bis.read(b);
str = new String (b);
str.trim();
System.out.print("The server says: "+str);
if (str.equals("BYE"))
{
bis.read(b);
str = new String (b);
System.out.print("The server says: "+str);
break one;
}
}

Related

UDP receive data

I'm programming about UDP in Mac with IntelliJ Idea.I tried to read data from client and print data that server receive.Here's the code.
Server
public class UDPServer {
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket(11111);
byte[] b = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(b,1024);
while (true){
datagramSocket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
InetAddress address = datagramPacket.getAddress();
String ip = address.getHostAddress();
String string = new String(data,0,data.length);
System.out.println("IP is "+ip+" "+string);
}
} }
Client
public class UDPClient {
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String dataString;
while((dataString = bufferedReader.readLine())!=null){
if(dataString.equals("886")){
System.out.println("UDPClient exit");
break;
}
DatagramPacket datagramPacket = new DatagramPacket(dataString.getBytes(),dataString.getBytes().length, InetAddress.getByName("192.168.3.2"),11111);
datagramSocket.send(datagramPacket);
}
datagramSocket.close();
}
}
I ran the Server first and then started the Client,and input something.Here's the input and print.
input
123456
abcdef
hello
print
IP is 192.168.3.2 123456����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
IP is 192.168.3.2 abcdef����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
IP is 192.168.3.2 hellof����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
1.the thrid print has another 'f'
2.at the end of every print there are many little squares(I don't have enough reputation to insert picture,sorry)
The problem is here in the server code:
String string = new String(data,0,data.length);
You're constructing a String based on the entire size of the data buffer, not the number of bytes received. As a result, if a packet is smaller that the last one, any additional bytes from that packet are still in the buffer.
You need to call datagramPacket.getLength() to get that value:
String string = new String(data,0,datagramPacket.getLength());

Why a new InputStreamReader won't read the remaining characters in the console?

So I have a very simple server written in Java:
public class SimpleServer {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("Server Socket created, waiting for client...");
Socket accept = serverSocket.accept();
InputStreamReader inputStreamReader = new InputStreamReader(accept.getInputStream());
int read;
System.out.println("Client connected, waiting for input");
while ((read = inputStreamReader.read()) != -1) {
System.out.print((char) read);
}
}
}
And here is a code that I use to connect to it:
public class SimpleClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost",8888);
OutputStreamWriter outputStream = new OutputStreamWriter(socket.getOutputStream());
InputStreamReader inputStreamReader;
char[] chars = new char[5];
while (true) {
System.out.println("Say something: ");
inputStreamReader = new InputStreamReader(System.in);
inputStreamReader.read(chars);
int x = 0;
for (int i=0;i<5;i++) {
if(chars[i]!='\u0000') {
x++;
}
}
outputStream.write(chars,0,x);
outputStream.flush();
chars = new char[5];
}
}
}
Now when I type something like this in the terminal of the Client:
123456789
I will see in the terminal of the Server:
Server Socket created, waiting for client...
Client connected, waiting for input
12345
However, when I change client as follows:
public class SimpleClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost",8888);
OutputStreamWriter outputStream = new OutputStreamWriter(socket.getOutputStream());
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
char[] chars = new char[5];
while (true) {
System.out.println("Say something: ");
inputStreamReader.read(chars);
int x = 0;
for (int i=0;i<5;i++) {
if(chars[i]!='\u0000') {
x++;
}
}
outputStream.write(chars,0,x);
outputStream.flush();
chars = new char[5];
}
}
}
then for the same input, I will see:
Server Socket created, waiting for client...
Client connected, waiting for input
123456789
My question is, System.out is a static variable which is already open and connected to the terminal in this case. Why is the information in the terminal lost when a new InputStreamReader object is created? Same terminal is passed to the object, isn't it?
Why is the information in the terminal lost when a new InputStreamReader object is created?
When you call read() on the InputStreamReader, it's allowed to (and often will) read more data from the stream than you've actually requested, and store the rest in a buffer, to satisfy later read calls. I suspect the whole of the line of text has actually been read by the first InputStreamReader, so when you construct a second InputStreamReader for the same stream, there's nothing left for it to read, and you'd have to type in more text to get it to do anything.

Not working Socket java software

I created an simple server/client application,but I could not use this one with two parameters,so I want to add two numbers on server,Two numbers sent to server as parameter.
But When I sent two parameters to server,the client and server begun to wait for anything and nothing happened,as if running both of them without results.
Server
class Server3 public static void main(String[] args)
{
try
(
ServerSocket server=new ServerSocket(12345);
Socket client=server.accept();
PrintWriter output=new PrintWriter(client.getOutputStream(),true);
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
)
{
int result=0;
String input;
while((input=in.readLine())!=null)
{
System.out.println(input);
result+=Integer.parseInt(input)*3;
//output.println("The result to client is "+result);
//output.flush();
}
output.println("The result to client is "+result);
output.flush();
}
}
}
Client
import java.net.*;
import java.io.*;
import java.util.*;
class Client3
{
public static void main(String[] args) throws Exception
try
(
Socket toServer=new Socket("localhost",12345);
PrintWriter output=new PrintWriter(toServer.getOutputStream(),true);
BufferedReader in=new BufferedReader(new InputStreamReader(toServer.getInputStream()));
)
{
String temp,input;
for(int i=0;i<args.length;++i)
{
output.println(args[i]);
output.flush();
}
while((input=in.readLine())!=null);
{
input=in.readLine();
}
System.out.println(input);
}
}
}
Do you hane any idea?
I tried a lot of things?
But never Can I use more numbers,I can use only without while condition.
You have to use a protocol to communicate between client and server. It's just like a way to talk about or you can say some rules to be followed while talking.
Sample code: (Read inline comments)
Here I used DONE as a token to tell the server that client has sent all the numbers and now I am waiting for the result.
Server:
Break the loop once all the numbers are received and sent the result back to client.
public class Server {
public static void main(String[] args) throws IOException {
try (ServerSocket server = new ServerSocket(12345);
Socket client = server.accept();
// flush automatically
PrintWriter output = new PrintWriter(client.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(
client.getInputStream()));) {
int result = 0;
String input;
while ((input = in.readLine()) != null) {
System.out.println(input);
if (input.equals("DONE")) { // Server received token DONE
break; // break the loop
}
result += Integer.parseInt(input) * 3;
}
// sent the result back to client
output.println("The result to client is " + result);
// output.flush();
// no need to call flush here
// because you have already set it to flush automatically
}
}
}
Client:
You don't need to put a while((input=in.readLine())!=null); to wait for received result.
public class Client {
public static void main(String[] a) throws Exception {
try (Socket toServer = new Socket("localhost", 12345);
// flush automatically
PrintWriter output = new PrintWriter(toServer.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(
toServer.getInputStream()));) {
for (int i = 0; i < args.length; ++i) {
output.println(args[i]); // sent all the numbers
// output.flush();
// no need to call flush here
// because you have already set it to flush automatically
}
output.println("DONE"); // Client sent token DONE
String input = in.readLine(); // read the result
System.out.println(input);
}
}
}
output: (server)
1
2
DONE
output: (client)
The result to client is 9

java BufferedReader specific length returns NUL characters

I have a TCP socket client receiving messages (data) from a server.
messages are of the type length (2 bytes) + data (length bytes), delimited by STX & ETX characters.
I'm using a bufferedReader to retrieve the two first bytes, decode the length, then read again from the same bufferedReader the appropriate length and put the result in a char array.
most of the time, I have no problem, but SOMETIMES (1 out of thousands of messages received), when attempting to read (length) bytes from the reader, I get only part of it, the rest of my array being filled with "NUL" characters. I imagine it's because the buffer has not yet been filled.
char[] bufLen = new char[2];
_bufferedReader.read(bufLen);
int len = decodeLength(bufLen);
char[] _rawMsg = new char[len];
_bufferedReader.read(_rawMsg);
return _rawMsg;
I solved the problem in several iterative ways:
first I tested the last char of my array: if it wasn't ETX I would read chars from the bufferedReader one by one until I would reach ETX, then start over my regular routine. the
consequence is that I would basically DROP one message.
then, in order to still retrieve that message, I would find the first occurence of the NUL char in my "truncated" message, read & store additional characters one at a time until I reached ETX, and append them to my "truncated" messages, confirming length is ok.
it works also, but I'm really thinking there's something I could do better, like checking if the total number of characters I need are available in the buffer before reading it, but can't find the right way to do it...
any idea / pointer ?
thanks !
The InputStream read method may return short reads; you must check the return value to determine how many characters were read, and continue reading in a loop until you get the number you wanted. The method may block, but it only blocks until some data is available, not necessarily all the data you requested.
Most people end up writing a "readFully" method, like DataInputStream, which reads the amount of data expected, or throws an IOException:
static public int readFully(InputStream inp, byte[] arr, int ofs, int len) throws IOException {
int rmn,cnt;
for(rmn=len; rmn>0; ofs+=cnt, rmn-=cnt) {
if((cnt=inp.read(arr,ofs,rmn))==-1) {
throw new IOException("End of stream encountered before reading at least "+len+" bytes from input stream");
}
}
return len;
}
Here is a sample server that I have used for testing
The main rcv is structured like
while((chars_read = from_server.read(buffer)) != -1)
{
to_user.write(buffer,0,chars_read);
to_user.flush();
}
The actual whole server is below ...
public static void main(String[] args) throws IOException
{
try
{
if (args.length != 2)
throw new IllegalArgumentException("Wrong number of Args");
String host = args[0];
int port = Integer.parseInt(args[1]);
Socket s = new Socket(host,port);
final Reader from_server = new InputStreamReader(s.getInputStream());
PrintWriter to_server = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader from_user = new BufferedReader(new InputStreamReader(System.in));
final PrintWriter to_user = new PrintWriter(new OutputStreamWriter(System.out));
to_user.println("Connected to " + s.getInetAddress() + ":" + s.getPort());
Thread t = new Thread()
{
public void run()
{
char [] buffer = new char[1024];
int chars_read;
try
{
while((chars_read = from_server.read(buffer)) != -1)
{
to_user.write(buffer,0,chars_read);
to_user.flush();
}
}
catch(IOException e)
{
to_user.println(e);
}
to_user.println("Connection closed by server");
to_user.flush();
System.exit(0);
}
};
t.setPriority(Thread.currentThread().getPriority() + 1);
t.start();
String line;
while ((line = from_user.readLine()) != null)
{
to_server.println(line);
to_server.flush();
}
//t.stop();
s.close();
to_user.println("Connection closed by client");
to_user.flush();
}
catch(Throwable e)
{
e.printStackTrace();
System.err.println("Usage : java TCPClient <hostname> <port>");
}
}

How to resolve a Stream Closed Error in java?

I am really thankful for everyone who would read this and try to help me, the following is the code I am trying to write for a server class for a socket-programming project for college:
import java.io.*;
import java.net.*;
import java.io.File;
class Server{
public static void main (String[]args)throws IOException{
ServerSocket socket1 = new ServerSocket (8000);
while (true) {
Socket incoming = socket1.accept();
new newclass(incoming).start();
}
}
}
class newclass extends Thread implements Runnable {
Socket incoming;
public newclass(Socket incoming) {
this.incoming = incoming;
}
public void run() {
try {
byte x = 0;
String z;
String s = "HTTP 1.0 200 Document follows";
String s1 = "Bad request message";
BufferedReader input = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
PrintWriter output = new PrintWriter(incoming.getOutputStream(), true);
DataOutputStream sending = new DataOutputStream(incoming.getOutputStream());
File directory = new File("C:\\Documents and Settings\\Ahmed\\Desktop\\bla\\Server");
File[] files = directory.listFiles();
int x1 = files.length;
if ((x1 - 3) < 10) {
boolean done = false;
while (!done) {
String line = input.readLine();
System.out.println(line);
if (line.equals("BYE")) {
output.println("BYE");
done = true;
} else {
if (line.trim().substring(0, 3).equals("GET ")) {
if (line.equals("<javalogo.png> HTTP 1.0")) {
File f = new File("javalogo.png");
int size = (int) f.length();
if (f.exists() == true) {
output.println(s);
output.println(size);
output.println("javalogo1.png");
DataInputStream bytefile = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));
while (bytefile.available() != 0) {
x = bytefile.readByte();
sending.write(x);
}
} else {
System.out.println("Getting file from main server");
Socket socket2 = new Socket("127.0.0.1", 8100);
BufferedReader bUsr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pOut = new PrintWriter(socket2.getOutputStream(), true);
BufferedReader bIn = new BufferedReader(new InputStreamReader(socket2.getInputStream()));
pOut.println("GET <javalogo.png> HTTP 1.0");
String rep = bIn.readLine();
if (rep.equals("HTTP 1.0 200 Document follows")) {
int len = Integer.parseInt(bIn.readLine());
String fname = bIn.readLine();
File f1 = new File(fname);
f1.createNewFile();
FileOutputStream fos = new FileOutputStream(f1);
DataInputStream dis = new DataInputStream(socket2.getInputStream());
for (int i = 0; i < len; i++) {
fos.write(dis.read());
}
fos.close();
} else if (rep.equals("File does not exist")) {
output.println("Sorry, but the file was neither found in the proxy server or the main server or the name is wrong.");
}
}
}
File f2 = new File("javalogo.png");
if (f2.exists() == true) {
int size = (int) f2.length();
output.println(s);
output.println(size);
output.println("javalogo.png");
DataInputStream bytefile = new DataInputStream(new BufferedInputStream(new FileInputStream(f2)));
while (bytefile.available() != 0) {
x = bytefile.readByte();
sending.write(x);
}
}
} else {
System.out.println(s1);
output.println(s1);
}
}
}
incoming.close();
}
output.println("Connecting to main server");
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
Now I don't understand why am I getting an error when I run the following client on it.
I get this really weird error where the buffered reader reads the first line from the user correctly but with the second one it gives me a null exception as if the client wrote null or something, I dont get it.
Here's the client code anyways, if anyone can help me I would be plenty thankful.
import java.net.*;
import java.io.*;
public class Client {
public static void main(String[] args) throws Exception {
Socket socket1 = new Socket("127.0.0.1", 8000);
BufferedReader bUsr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pOut = new PrintWriter(socket1.getOutputStream(), true);
BufferedReader bIn = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
String cmd;
String rep;
while (true) {
cmd = bUsr.readLine();
pOut.println(cmd);
System.out.println(rep = bIn.readLine());
if (cmd.equals("BYE") || cmd.equals("END"))
break;
else if (rep.equals("HTTP 1.0 200 Document follows")) {
int len = Integer.parseInt(bIn.readLine());
String fname = bIn.readLine();
File f = new File(fname);
f.createNewFile();
FileOutputStream fos = new FileOutputStream(f);
DataInputStream dis = new DataInputStream(socket1.getInputStream());
for (int i = 0; i < len; i++) {
fos.write(dis.read());
}
fos.close();
System.out.println("Success");
} else if (rep.equals("Connecting to main server")) {
Socket socket1 = new Socket("127.0.0.1", 8100);
BufferedReader bUsr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pOut = new PrintWriter(socket1.getOutputStream(), true);
BufferedReader bIn = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
String cmd;
String rep;
while (true) {
cmd = bUsr.readLine();
pOut.println(cmd);
System.out.println(rep = bIn.readLine());
if (cmd.equals("BYE") || cmd.equals("END"))
break;
else if (rep.equals("HTTP 1.0 200 Document follows")) {
int len = Integer.parseInt(bIn.readLine());
String fname = bIn.readLine();
File f = new File(fname);
f.createNewFile();
FileOutputStream fos = new FileOutputStream(f);
DataInputStream dis = new DataInputStream(socket1.getInputStream());
for (int i = 0; i < len; i++) {
fos.write(dis.read());
}
fos.close();
System.out.println("Success");
}
}
}
bIn.close();
pOut.close();
socket1.close();
}
}
This is the first time asking anything on this site, so if I did anything wrong I would be more than happy to change what I wrote.
By the way, the part in the server which states "getting file from main server" is a part where the server itself becomes a client for a main server, from where it gets the file and sends it to the client, I didn't add the main server code because it'd be too much code but basically it's the same as server without the if condition restricting it to 10 files in the directory only.
In general, when there is a NullPointerException either:
You have not instantiated your object
Your object has been destroyed (closed) and therefore does not exist
You have an invalid cast
Your code has overwritten your object pointer
You would need to examine your stack dump to see which of these is true.
From the Jav Docs the read can throw IOException if an I/O error occurs and IOException can give you the specified detail message. The error message string can later be retrieved by the Throwable.getMessage() method of class java.lang.Throwable.
Two points:
What does the IOException detail give you?
Since this is for your college course, try asking your classmates or TA for assistance
I'd be lying if I said I fully understand what your code is doing - But if you are getting null data when you are reading from a stream which you expect to contain data it could be that the output stream hasn't 'flushed' the data.
Make sure you call the flush() method on your Output streams after you have written to them
Ahemd, I see a number of potential errors and some actual bugs too in the classes as posted, but the code is too complicated for me to focus on the issue you are seeing. If you're still experiencing network bugs, try reducing the code and both client and server to the minimal possible to get communication going (send/read one line). If that doesn't work for you, post those classes and we'll be able to see the problems much more quickly than with the larger classes posted here.
Good luck.
If you are getting null from a BufferedReader.readLine() it means you have reached the end of input as it states in the javadoc for this method.
The best way to find your errors solution , is to see a trace. Without it I see more than one error in your code.
Regards.

Categories