I just want to send data to another device (PC) using UDP by clicking on a button. So I made a method for it in which I put the UDP code and made a relation when button is clicked. But according to the IDE, the byte which contains the String data I want to send is not well created.
Here's the code:
String argv = "WhatISend";
int port = 9268;
byte[] buffer= new byte[argv.lenght()];
try {
InetAddress server = InetAddress.getByName("172.16.19.14");
buffer = argv.getBytes();
DatagramSocket socket = new DatagramSocket();
DatagramPacket udp_emission = new DatagramPacket(buffer, buffer.length, server, port);
socket.send(udp_emission);
socket.close();
} catch (Exception e) {
System.out.println("Fail socket");
}
the problem is on "byte[] buffer= new byte[size];"
Based on the wording of your question, it sounds like you want buffer to contain the characters of the original string. However, the byte array actually does not contain the string data. The code you have shown us just creates a byte array that has the same length as the input string. You have not assigned the individual characters over to the buffer.
What you probably want is this:
buffer = argv.getBytes();
For more information, see String.getBytes().
Related
Here is my Sender program
import java.net.*;
class Send{
public static void main(String[] args) {
try{
//setup
DatagramSocket socket=new DatagramSocket();
byte[] buffer=new byte[100];
InetAddress address=InetAddress.getLocalHost();
System.out.println("Address:"+address);
DatagramPacket packet=new DatagramPacket(buffer,buffer.length,address,10000);
//get data
String data="Hello";
//send data
buffer=data.getBytes();
System.out.println("Sending data");
socket.send(packet);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
Here is the Receiver Program
import java.net.*;
class Listen{
public static void main(String[] args) {
try{
//set up
DatagramSocket socket=new DatagramSocket(10000);
byte[] buffer=new byte[100];
DatagramPacket packet=new DatagramPacket(buffer,buffer.length);
//recieve
System.out.println("Started Listening");
socket.receive(packet);
//print
String receivedData=new String(packet.getData());
System.out.println(receivedData);
System.out.println("Done!");
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
What I get is, when the Listener is running, it seems to be waiting for the sender to send data(prints "started Listening"). When sender is executed, it seems to run properly as well(prints "Sending data"). receiver executes further as well(prints "Done!"), but the packet remains empty.
What might be the problem?
The problem is that you never put anything in the packet. First you create an empty packet, then you fill a buffer with data - but that buffer isn't used in the packet.
Reverse the order of things:
String data="Hello";
//get data
// HERE : first put data in the buffer, THEN build the packet
byte[] buffer=data.getBytes();
InetAddress address=InetAddress.getLocalHost();
System.out.println("Address:"+address);
DatagramPacket packet=new DatagramPacket(buffer,buffer.length,address,10000);
//send data
System.out.println("Sending data");
socket.send(packet);
As Jon Skeet mentioned, you also need to worry about character encodings on both ends. If you don't specify an encoding when you do String.getBytes() or new String(byte[]) on the receiving side, then you will use the default character encoding on your computer. Which is fine if you're on the same computer, but can create a lot of problems if the sender and receiver are on different computers and the computers have different platform default character encodings.
So you need to specify the encoding, and your best best is probably UTF8, if most of the text you send is using the Latin script.
So on the sending side:
byte[] buffer = data.getBytes(StandardCharsets.UTF_8);
And on the receiving side:
String receivedData = new String(packet.getData(), StandardCharsets.UTF_8);
You are creating the data packet before filling the buffer with your data, hence you're sending an empty buffer.
Change the order of the lines as follows and your program works as expected:
//get data
String data="Hello";
buffer=data.getBytes();
DatagramPacket packet=new DatagramPacket(buffer,buffer.length,address,10000);
I know TCP is better to send file but I have a homework about sending file via udp protocol . Is there any code example in C# or Java about sending file?
I have server-client example to send and recieve message. I tried to send the file using the same way but could not succeed. I may need an algorithm to divide the file small parts and send them via datagram, and I have an idea to put "md5" of the part as header of the array to check if the packet is lost or not.
Here is my try , my server side in java;
// 1. creating a server socket, parameter is local port number
sock = new DatagramSocket(7777);
// buffer to receive incoming data
byte[] buffer = new byte[65536];
DatagramPacket incoming = new DatagramPacket(buffer, buffer.length);
byte []bigByteArray=new byte[1024*1024*1024*1024];
// 2. Wait for an incoming data
echo("Server socket created. Waiting for incoming data...");
ByteBuffer target = ByteBuffer.wrap(bigByteArray);
// communication loop
while(true)
{
try
{
sock.receive(incoming);
String s = new String(incoming.getData());
if(s=="finish") break;
target.put(incoming.getData());
}
catch(Exception e)
{
}
}
fos.write(bigByteArray);
fos.close();echo("RECIEVED");
and my client side;
String s;
Path path=Paths.get("C:\\Users\\Toshiba\\Desktop\\aa.txt");
byte[] data = Files.readAllBytes(path);
try
{
sock = new DatagramSocket();
InetAddress host = InetAddress.getByName("localhost");
//take input and send the packet
byte [] part;
for (int i = -1; i < data.length; i=i+100)
{
if(sock.isConnected())
{
part=Arrays.copyOfRange(data,i+1,i+100 );
}
else i=i-100;
}
byte [] f="finish".getBytes();
DatagramPacket finalpac = new DatagramPacket(f ,f.length , host , port);
sock.send(finalpac);
}
Thank you in advance.
Several issues:
The following isn't correct:
sock.receive(incoming);
String s = new String(incoming.getData());
The final line should be
String s = new String(incoming.getData(), incoming.getOffset(), incoming.getLength());
and if you aren't receiving text you shouldn't be converting the data to a String at all.
Remove the sock.isConnected() test. DatagramSockets are not usually connected, and you certainly haven't connected this one.
The loop in which this is embedded does nothing useful. You are only sending the word "finish".
I'm facing UDP packet loss problem based on Android devices. I have two devices. Following code works correctly on one device. The other device lost many packages. I have already read solution of similar problem. In this solution, setting the datagram socket size to 64k is suggested. But I couldn't set it.
How can I change datagram buffer size?
My code:
DatagramSocket udpSocket = null;
try {
udpSocket = new DatagramSocket(5004);
udpSocket.setReceiveBufferSize(64*1024);
Log.d("UDPSocket", "Buffer Size : " + udpSocket.getReceiveBufferSize());
} catch (SocketException e1) {
e1.printStackTrace();
}
Log:
05-14 10:34:05.960: D/UDPSocket(28021): Buffer Size : 112640
Author of the chosen anwser seems to have problems using past tense and speak to present nearly all time, but at one point he exactly say
I removed this code setting buffer size and then it strated receving all the packets
So in fact it was changing datagram buffer size wich seems to have caused it's problem.
By the way, your method to set buffersize probably work, in fact log message respond to you with your platform buffer size, wich you can't change, see Android DatagramSocket receive buffer size.
I resolved my problem.
I changed my receive data code.
Past code:
byte[] receiveData = new byte[1328];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
try {
udpSocket.receive(receivePacket);
} catch (IOException e) {
e.printStackTrace();
}
New code:
ParcelFileDescriptor parcelFileDescriptor = ParcelFileDescriptor.fromDatagramSocket(udpSocket);
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
FileInputStream fin = new FileInputStream(fileDescriptor);
byte[] receiveData = new byte[1328];
int readByte = fin.read(receiveData);
I have a problem with writing an reading an array of bytes from client to server. The client actually writes all the bytes but the server does not seem to be able to read it. Here is the code for the client and server sides
Socket sock = new Socket(Interface.SERVER_IP, 4444);
PrintStream os = new PrintStream(sock.getOutputStream());
os.println("3");
DataOutputStream dOut = new DataOutputStream(sock.getOutputStream());
dOut.writeInt(data.length); // byte array created above
dOut.write(data);
and the server side is:
DataInputStream clientData = new DataInputStream(clientSocket.getInputStream());
int length = clientData.readInt();
System.out.println(length);
byte[] data = new byte[length]; // read length of incoming message
if(length>0) {
clientData.readFully(data, 0, data.length); // read the message
}
The server seems to be blocked at the line to read the length of the byte array. Please I really need help solving this
After you write the data, flush the output:
dOut.writeInt(data.length); // byte array created above
dOut.write(data);
dOut.flush();
Alternatively, close the stream (if you aren't going to use it again)...
dOut.writeInt(data.length); // byte array created above
dOut.write(data);
dOut.close();
Also note that your PrintWriter is printing a string value (of "3"). You are printing extra data to the stream that doesn't seem to get consumed on the server.
You're printing "3" to the socket but you're never reading it. So when you do readInt(), you're reading the "3" and a line terminator instead.
Don't mix multiple streams/writers on the same socket. Use the same ones for the life of the socket.
I'm starting to write my first Java networking program, and long story short I'm having difficulty making sure that I'm taking the right approach. Our professor has given us a server program to test against this UDP client, but I'm getting some errors I can't seem to squash. Specifically, I get IO exceptions, either "Connection Refused" or "No route to host" exceptions.
public class Lab2Client {
/**
* #param args[1] == server name, args[2] == server port, args[3] == myport
*/
public static void main(String[] args) {
//Serverport is set to 10085, our client is 10086
try {
Socket echoSocket = new Socket(args[0],Integer.parseInt(args[2]));
System.out.println("Server connection Completed\n");
DataOutputStream output = new DataOutputStream(echoSocket.getOutputStream());
byte[] toSend = new byte[5];
toSend[0] = 12; toSend[1] = 34;//Code Number
toSend[2] = 15;//GroupId
toSend[3] = 86;toSend[4] = 100;//Port number in Little Endian Order
output.write(toSend);
System.out.println("Sent Request. Waiting for reply...\n");
DataInputStream input = new DataInputStream(echoSocket.getInputStream());
byte[] toRecieve = new byte[]{0,0,0,0,0,0,0,0};
input.read(toRecieve);
checkMessage(toRecieve);
}
catch (UnknownHostException e) {
System.err.println("Servername Incorrect!");
System.exit(1);
}
catch (IOException e){
System.err.println("IO Exception. Exiting...");
System.err.println(e);
System.exit(1);
}
}
I also have some questions about my implementation regarding receiving messages in Java. I'll be getting a datagram that contains either:
a) 3 formatting bytes (unimportant to the question) along with an IP and port number
or
b) 3 formatting bytes and a port.
Is using a DataInputStream the correct way to do this? I know using an array with 9 elements is lazy instead of dynamically allocating one that's either 5 or 9, but right now I'm just trying to get this working. That being said, is there a different approach anyone would suggest for this?
You need not to wrap the stream returned by Socket.getOuputStream() with DataOutputStream - it is already the DataOutputStream
In this line:
Socket echoSocket = new Socket(args[0],Integer.parseInt(args[2]));
I suppose it should be args[1], not args[0].
Here you have to convert the integer value to its byte representation:
toSend[3] = 10086 & 0xFF;toSend[4] = 10086>>8; //Port number in Little Endian Order
Answer to your question: case b as you are not sending the IP
thought I'd leave this up for posterity. The problem is simple, and I'm a fool for not noticing it sooner.
The correct programs I was testing this against used the UDP protocol, and this program is written in TCP. The corrected code is:
public class Lab2Client {
/**
* #param args[0] == server name, args[1] == server port, args[2] == myport
*/
public static void main(String[] args) {
//Serverport is 10085, our client is 10086
try {
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName(args[0]);
int portToSend = Integer.parseInt(args[2]);
System.out.println("Clent Socket Created");
byte[] toSend = new byte[5];
toSend[0] = 0x12; toSend[1] = 0x34;//Code Number
toSend[2] = 15;//GroupId, f in hex
toSend[3] = 0x27;toSend[4] = 0x66;
System.out.println("Byte Array Constructed");
DatagramPacket sendPacket = new DatagramPacket(toSend, toSend.length, IPAddress, Integer.parseInt(args[1]));
clientSocket.send(sendPacket);
System.out.println("Sent Request. Waiting for reply...\n");
DataInputStream input = new DataInputStream(echoSocket.getInputStream());
toRecieve can either be an error message, a return of what we sent,
or a byte stream full of IP info and port numbers.
the "heavy" byte stream is either 4 for IPv4 of 16 for IPv6, 2 bytes for port,
and the magic number (2 bytes) for a total of 9-20 bytes*/
byte[] toRecieve = new byte[9];
DatagramPacket receivePacket = new DatagramPacket(toRecieve, toRecieve.length);
clientSocket.receive(receivePacket);
checkMessage(toRecieve);
} //and so on and so forth...
Thanks to #Serge for the help, though nobody could have answered my question correctly with how I asked it. The byte shifting you suggested was important too.