I have a simple server-client program that takes info from the client and passes it to the server. The messages are passed through a DatagramSocket. The server then takes the message and writes it to a text file.
My initial message works fine(gets printed to the file). However, if I run the client again then the new message does not get written to the file. I have to RESTART the server for the message to be printed again.
I have an arrayCopy method that copies two arrays and puts it into a larger array.
CLIENT
public static void main(String[] args) throws IOException {
System.out.println("Enter Username");
BufferedReader usernameInput = new BufferedReader(new InputStreamReader(System.in));
// Get the Username
String username = directoryInput.readLine();
byte[] usrname = username.getBytes();
//Copy Username to Array
byte[] tempArray = copyarray(packetheader, usrname);
buffer = tempArray;
mypacket = new DatagramPacket(buffer, buffer.length, IPaddr, 40000);
clientSocket = new DatagramSocket();
clientSocket.send(mypacket);
Server
public static void main(String args[]) throws Exception {
String Database;
textfile = "C:\\textfile.txt";
DatagramSocket serverSock = new DatagramSocket(40000);
byte[] rbuf = new byte[97];
DatagramPacket recievedPacket = new DatagramPacket(rbuf, rbuf.length);
serverSock.receive(recievedPacket);
String byteToString = new String(recievedPacket.getData(), 0, recievedPacket.getLength(), "US- ASCII");
FileWriter fstream = new FileWriter(textfile);
BufferedWriter out = new BufferedWriter(fstream);
out.write(byteToString);
out.close
}
The following should do what you want, what you need is a loop that allows you to read the next package, and the next and so on.
public static void main(String args[]) throws Exception {
String textfile = "C:\\textfile.txt";
DatagramSocket serverSock = new DatagramSocket(40000);
byte[] rbuf = new byte[97];
DatagramPacket recievedPacket = new DatagramPacket(rbuf, rbuf.length);
while(true) {
serverSock.receive(recievedPacket);
String byteToString = new String(recievedPacket.getData(), 0, recievedPacket.getLength(), "US-ASCII");
FileWriter fstream = new FileWriter(textfile);
BufferedWriter out = new BufferedWriter(fstream);
out.write(byteToString);
out.close();
recievedPacket.setLength(rbuf.length);
}
}
However, this will overwrite the file with the new message, not append them (if that is what you wanted). If you want to store all messages you probably want to move the file creation out of the loop.
Related
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());
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.
For a homework i try to send a file and some parameter corresponding to this file.
So, i send my file and after my string.
The problem is my paramater go to my file and not in my variable. I understand the problem, my loop while continue to write in the file as long as he receives something, but i want to stop it and have my parameter outside from my file.
Here my code client:
public static void transfert(InputStream in, OutputStream out) throws IOException{
PrintWriter printOut;
byte buf[] = new byte[1024];
int n;
while((n=in.read(buf))!=-1)
out.write(buf,0,n);
printOut = new PrintWriter(out);
printOut.println("add");
System.out.println("envoie !!!");
printOut.println("1");
printOut.println("3");
// out.write(getBytes("add"),0,0);
printOut.flush();
}
and here my server code :
public static void transfert(InputStream in, OutputStream out, boolean closeOnExit) throws IOException
{
byte buf[] = new byte[1024];
int n;
while((n=in.read(buf))!=-1)
out.write(buf,0,n);
buffIn = new BufferedReader (new InputStreamReader(in));
String nom_methode = buffIn.readLine();
String param1 = buffIn.readLine();
String param2 = buffIn.readLine();
System.out.println("methode:"+nom_methode+"param1:"+param1+"param2:"+param2);
if (closeOnExit)
{
in.close();
out.close();
}
}
edit:
I still miss something, now i have an error with my thread, i think the problem is from my loop wich read my file in input.
Moreover, actually param still go in my file and not in my param... Why the loop dont stop after EOF ?
error:
Exception in thread "Thread-0" java.lang.IndexOutOfBoundsException
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:318)
at serveurthread.AcceptClient.transfert(AcceptClient.java:45)
at serveurthread.AcceptClient.run(AcceptClient.java:84)
at java.lang.Thread.run(Thread.java:722)
client:
public static void transfert(InputStream in, OutputStream out) throws IOException{
PrintWriter printOut;
printOut = new PrintWriter(out);
byte buf[] = new byte[1024];
int n;
while((n=in.read(buf))!=-1)
out.write(buf,0,n);
printOut.print('\u0004');
printOut.flush();
printOut.println("add");
System.out.println("envoie !!!");
printOut.println("1");
printOut.println("3");
// out.write(getBytes("add"),0,0);
printOut.flush();
}
server:
public static void transfert(InputStream in, OutputStream out, boolean closeOnExit) throws IOException
{
byte buf[] = new byte[1024];
int n;
while((n=in.read(buf))!= (int)'\u0004'){
out.write(buf,0,n);
}
buffIn = new BufferedReader (new InputStreamReader(in));
String nom_methode = buffIn.readLine();
String param1 = buffIn.readLine();
String param2 = buffIn.readLine();
System.out.println("methode:"+nom_methode+"param1:"+param1+"param2:"+param2);
if (closeOnExit)
{
in.close();
out.close();
}
}
You are going to need some kind of marker in your stream that signifies the end of the file. I suggest '\u0004' which is the EOF character. Basically, write this character after writing the file, then adjust the loop in the server like this:
while((n=in.read(buf))!=(int)'\u0004')
out.write(buf,0,n);
Now, the server stops reading the file when necessary, then can get around to reading the string.
Also, read returns a count of bytes read, not a char. I would pass one byte at a time through, by declaring bytes instead of byte arrays.
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;
}
}
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.