UDP receive data - java

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());

Related

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

Simple socket-level program - client/server

The following is a simple socket-level program. Once a connection is established, the server speaks for as long as he/she wants provided that the message does not end in a period - then the client can speak for as long as he/she wants provided that the conversation does not end in a period - the conversation alternates like this until someone shuts the program down --
I can't get the until there is a period part down ...
Else, I would not have a problem - there would be a one-one interaction
Once one person writes, it stays their turn forever ...
import java.io.*;
import java.net.*;
public class ChatterServer {
final static int SERVER_PORT = 3333;
public static void main(String [] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(SERVER_PORT);
System.err.println("Waiting for a client");
Socket clientSocket = serverSocket.accept();
System.out.println("Connection requested from: " + clientSocket.getLocalAddress());
PrintStream toClient = new PrintStream(clientSocket.getOutputStream(), true);
BufferedReader fromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
toClient.println("Whatcha want?");
String incoming = fromClient.readLine();
while(incoming != null) {
System.out.println(incoming);
System.out.print("Your turn>");
String myReply="";
//this part does not work
while ( myReply.substring( myReply.length() ) .equals(".") == false){
myReply = keyboard.readLine();
toClient.println(myReply);
}
incoming = fromClient.readLine();
}
}
}
import java.io.*;
import java.net.*;
public class ChatterClient {
final static int SERVER_PORT = 3333;
public static void main(String [] args) throws Exception {
Socket serverSocket = new Socket(args[0], SERVER_PORT);
PrintStream toServer =
new PrintStream(serverSocket.getOutputStream(), true);
BufferedReader fromServer = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
String incoming = fromServer.readLine();
while(incoming != null) {
System.out.println(incoming);
System.out.print("Your turn>");
String myReply="";
while ( myReply.substring( myReply.length() ) .equals(".") == false){
myReply = keyboard.readLine();
toServer.println(myReply);
}//end while
incoming = fromServer.readLine();
}//end while
}//end main
}//end ChatterClient class
Better would be to use the endsWith method. It will work just fine, and is cleaner to look at.
while (!myReply.endsWith(".")){...}
While I agree with using String.endsWith the actual problem in the code is that someString.substring(someString.length()) will always be an empty string. You wanted someString.substring(someString.length()-1).

Simple Client Server program

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;
}
}

BufferedWriter only works the first time

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.

Categories