JAVA - Can't make a UDP packets reach it destination with the code, but it works in "Packet Sender", Wireshark shows the same status - sockets

I'm trying to send a UDP packet over a local network in my workplace.
until now I used a program called "Packet Sender", and it worked fine, but my boss asked me to write a code in Java that does the same.
When the packet arrives to its destination it turns off one of the lights in the office (like in Home automation).
Since the light isn't turned off with my code and only with packet sender I understand that something is wrong, but I don't know what.
I wrote this code:
import java.io.*;
import java.net.*;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
public class UDPSend
{
public static void main(String args[])
{
try {
int port = 6670;
//Send Hex As Bytes
HexBinaryAdapter adapter = new HexBinaryAdapter();
byte[] message = adapter.unmarshal("020000c818010000020300");
// Get the internet address of the specified host
InetAddress address = InetAddress.getByName("172.16.254.254");
// Initialize a datagram packet with data and address
DatagramPacket packet = new DatagramPacket(message, message.length,
address, port);
// Create a datagram socket, send the packet through it, close it.
DatagramSocket dsocket = new DatagramSocket();
dsocket.send(packet);
dsocket.close();
} catch (Exception e) {
System.err.println(e);
}
}
}
now just so you'll can understand my problem better, here are some printscreens:
www32.speedyshare.com/PrUcv/download/stack-over-flow.png
1] - The wireshark printscreen when I run my code.
2] - The Packet Sender with all the data to send.
3] - the Packet Sender log in which you can see it sent the packet and it did what it
supposed to do.
4] - the Wireshark monitor when I run the packet sender application.
IMPORTANT!!
1. I'm trying to run the code in the office network.
2. I KNOW the 2 last chars in the packet sender is 01 and in the JAVA code is
00, it's OK! one turn the light on and the other one off, either
way it works with packet sender but not with my code.
3. Wireshark shows a bad checksum to my code as well to the packet sender app, the difference is that when I use the packet sender it works despite the bad checksum.

Related

Monitoring UDP data on wireshark shows ARP packet

I am trying to send UDP packet to my server 10.20.1.2 with port number 20000. I have implemented UDP client on PC and when i send data using sendto API , at the same time i monitor data on wireshark wireshark shows it as an ARP packet.
18967 5440.858646 PcsCompu_ef:b4:89 Broadcast ARP 42 Who has 10.20.1.2? Tell 192.168.1.70
192.168.1.70 is my machine ip where UDP client is running.
I am not sure how UDP packet is getting converted into ARP packet ?
I understand ARP is for finding MAC address of target node but here i already know MAC address of target device , How can i add it in my udp client so it directly starts UDP communication . My target device is one embedded camera , i am not expecting it to reply on ARP request so i want to prevent sending ARP request.
Below is my UDP client code :
Any inputs are highly appreciated. Thanks in advance.
/*
Simple udp client
*/
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //exit(0);
#include<arpa/inet.h>
#include<sys/socket.h>
#define SERVER "10.20.1.2"
#define PORT 20000 //The port on which to send data
char message[3]={0x00, 0x00 , 0x24};
int main(void)
{
struct sockaddr_in si_other;
int s, i, slen=sizeof(si_other);
int ret;
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("socket failed");
}
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SERVER , &si_other.sin_addr) == 0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
ret = sendto(s, message, sizeof(message) , 0 , (struct sockaddr *) &si_other, slen);
close(s);
return 0;
}
Some clarifications regarding networking.
1. ARP must be sent and replied
Your camera has IP interface, which means it must handle ARP requests fine without any doubts. ARP is essential part of communicating via IP, camera without ARP support makes no sense. And ARP isn't a result of converting UDP, it's a preliminary step before sending actual UDP datagram. Once ARP reply is discovered with destination MAC-address, UDP packet is sent to that destination. The issue you see isn't about hardcoding MAC to avoid ARP.
2. Your code looks fine
Compiled it locally with minor corrections (missing #include <unistd.h> header with close() declaration), tested on several targets, client works as expected.
3. Something is wrong with your network topology
You are sending message from 192.168.1.70 to 10.20.1.2, which is weird. 192.168.0.0/24 and 10.0.0.0/8 are private IP addresses from different ranges, so they normally can't reach each other without black magic (like NAT traversal). And, what is much weirder, during your attempt ARP request is sent to strange destination. Let me illustrate different cases:
if both devices are in same subnet (e.g. 192.168.1.70 sends to 192.168.1.71), then message is sent directly, so client asks "who has 192.168.1.71" in ARP request.
if devices are in different subnets (e.g. 192.168.1.70 sends to 8.8.8.8), then message is sent through gateway, thus ARP request reads "who has 192.168.1.1" or whatever your gateway address is. Gateway MAC may be already in cache, in which case ARP isn't sent at all.
in your case subnets are obviously different, but ARP is asking about direct destination address rather than gateway MAC address.
It's a shot in the dark, but probably you have two network interfaces on your PC, one connected to 192.168.0.0 subnet, the other to 10.0.0.0 and ARP request is sent from both. If you sniff the wrong interface, you see weird ARP request and don't see UDP, which is actually sent after it. By the way, seeing single arp request is also confusing, because it should be repeated several times if noone answers.
Anyway, you need to check network topology and/or simplify it. Remove unnecessary network interfaces, configure PC and camera to be on the same subnet connected to the same switch/router and investigate further.

using socket package for octave on ubuntu

I am trying to use the sockets package for Octave on my Ubuntu. I am using the Java Sockets API for connecting to Octave. The Java program is the client, Octave is my server. I just tried your code example:
http://pauldreik.blogspot.de/2009/04/octave-sockets-example.html
There are two problems:
1.)
Using SOCK_STREAM, for some strange reason, certain bytes are being received by recv() right after accept(), even if I'm not sending anything from the client. Subsequent messages I send with Java have no effect, it seems the Octave socket completely has its own idea about what it thinks it receives, regardless of what I'm actually sending.
2.)
Using SOCK_DGRAM, there is another problem:
I do get a reception of my actual message this way, but it seems that a recv() command doesn't remove the first element from the datagram queue. Until I send the second datagram to the socket, any subsequent recv() commands will repeatedly read the first datagram as if it were still in the queue. So the recv() function doesn't even block to wait for an actually new available datagram. Instead, it simply reads the same old one again. This is useless, since I cannot tell my server to wait for news from the client.
Is this how UDP is supposed to behave? I thought datagram packets are really removed from the datagram queue by recv().
This is my server side code:
s=socket(AF_INET, SOCK_DGRAM, 0);
bind(s,12345);
[config,count] = recv(s, 10)
[test,count] = recv(s, 4)
And this is my Java client:
public LiveSeparationClient(String host, int port, byte channels, byte sampleSize, int sampleRate, int millisecondsPerFrame) throws UnknownHostException, IOException {
this.port = port;
socket = new DatagramSocket();
this.host = InetAddress.getByName(host);
DatagramPacket packet = new DatagramPacket(ByteBuffer.allocate(10)
.put(new byte[]{channels, sampleSize})
.putInt(sampleRate)
.putInt(millisecondsPerFrame)
.array(), 10, this.host, port
);
socket.send(packet);
samplesPerFrame = (int) Math.floor((double)millisecondsPerFrame / 1000.0 * (double)sampleRate);
}
As you see, I'm sending 10 Bytes and receiving all 10 (this works so far) with recv(s, 10). In the later part of my Java program, packets will be generated and send also, but this may take some seconds. In the mean time, the second receive, recv(s, 4), in Octave should wait for a really new datagram package. But this doesn't happen, is simply reads the first 4 Bytes of the same old package again. recv() doesn't block the second time.
I hope it is not a problem for you to fix this?
Thanks in advance :-)
Marvin
P.S.: Also, I don't undertstand why listen() and accept() are both necessary when using SOCK_STREAM, but not for SOCK_DGRAM.

UDP Listen, Send Receive (Simple, Client and Server on same app)

Okay, I want to send a UDP packet to an IP, and then receive it.
As I can't get it to work, I have to ask for assistance.
I want it to work on 1 app, meaning client and server is on the same application.
I currently got it working with Audio sending and receiving on the same app (using sample codes and stuff).
And the thing I can´t understand is just the UDP, and probably Sockets.
It seems simple, but I can´t get it to work.
So if I can get a very simple sample, like:
"UDP Send "hello" to IPofchoice"
"UDP receive "data" from IPofchoice"
Messagebox.show("decoded(data));
Well hope you get what I mean.
EDIT:
Here is my "example" which doesn´t work at all.
void VoiceChat_KeyPress(object sender, KeyPressEventArgs e)
void VoiceChat_KeyPress(object sender, KeyPressEventArgs e)
{
string text = "Hello";
byte[] send_buffer = Encoding.ASCII.GetBytes(text);
otherPartyIP = new IPEndPoint(IPAddress.Parse(txtCallToIP.Text), 1450);
udpClientKey.Send(send_buffer, send_buffer.Length, "127.0.0.1", 1450);
byte[] byteData = udpClientKey.Receive(ref otherPartyIP);
MessageBox.Show(otherPartyIP.Address.ToString());
MessageBox.Show(System.Text.Encoding.ASCII.GetString(byteData));
}
Where txtCallToIP.tex = the ip i write, which is 127.0.0.1 currently.
This i solved.
To have a client and server in UDP it´s very easy, though a bit dangerous, as you don´t know for sure if it´s working or not unless you test it (UDP just send and don´t care about anything else).
So basically to do it.
Client.Send(buffer,0,buffer.size,IPAdress,Port);
byte[] rec = Client.Receive(ref IPAdress);
To receive you must have bind it to an IP, so you can just bind it to listen to Any ipadress,
The port however needs to be set (i think), and you want to do that, as listening to everything there is, is not a good idea.
So ref IPAdress will be that listening IP and Port.
So it´s very easy to set up. And you can use the same UDPClient for both receiving and sending if you want, though it´s probably better to have 2 separate .

Socket.SendTo() and headerincluded

i have used socket name space to establish connection between two system, now i am able to send and receive message , now i want to get information about packet that has been received , like header information( sender Address , ttl and ... )
int sendCount = 1;// Number of times to send the response
int bufferSize = 4096;// Size of the send and receive buffers
IPAddress localAddress = IPAddress.Any;
SocketType sockType;
ProtocolType sockProtocol;
int rc;
Socket clientSocket;
byte[] receiveBuffer, sendBuffer;
Socket serverSocket = null;
You don't receive packets with TCP, you receive byte streams.
You can get the sender's remote address and remote port from the accepted socket, once you have it.
You can't get the TTL of a packet at all without going to a much lower layer where you don't wanna go, believe me.

sendto not working on VxWorks

I asked this question before and had no resolution (still having the problem). I am stumped because the function returned without error and NO DATA was sent! This code works on Linux ... the VxWorks version does not work (sendto does not send, though it returns without an ERROR).
The synopsis - I am writing a simple echo server - The server successfully receives
the data (from an x86 box) and claims it successfully SENT it back.
However NO DATA is received on the client (netcat on an x86). This
code is running on VxWorks 5.4 on a PowerPC box ...
I is the UDP data being buffered somehow?
Could another task be preventing sendto from sending? (NOT to get off on a wild goose chase here, but I taskspawn my application with a normal priority, i.e. below critical tasks like the network task etc etc ... so this is fine).
Could VxWorks be buffering my UDP data?
I HAVE setup my routing table ... pinging works!
There is NO firewall AFAIK ...
What are the nuances of sendto and what would prevent my data from
reaching the client ...
while(1)
{
readlen = recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *) &client_address, &slen);
if (readlen == ERROR)
{
printf("RECVFROM FAILED()/n");
return (ERROR);
}
printf("Received %d bytes FROM %s:%d\nData: %s\n\n",
readlen, inet_ntoa(client_address.sin_addr),
ntohs(client_address.sin_port), buf);
// Send it to right back to the client using the open UDP socket
// but send it to OUTPORT
client_address.sin_port = htons(OUTPORT);
// Remember slen is a value (not an address ... in, NOT in-out)
sendlen = sendto(sock, buf, BUFLEN, 0, (struct sockaddr*)&client_address, slen);
// more code ....
}
I trust ERROR is defined as -1, right? Then are you checking the return value of the sendto(2) call? What about the errno(3) value?
One obvious problem I see in the code is that you give BUFLEN as length of the message to be sent, while it should actually be readlen - the number of bytes you received.