I'm running Kannel and Smppsim on a virtual machine and sending SMPP packets through them. I see the packets on Wireshark, but when I try to capture them with a datagram packet in java I receive nothing.
Here's my code:
DatagramSocket ds = new DatagramSocket(2775);
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 1024);
ds.receive(dp);
String str = new String(dp.getData(), 0, dp.getLength());
System.out.println(str);
ds.close();
I was doubtful about the port number so I also tried port 60720.
and here's an example of the packet I'm receiving on Wireshark:
I don't know what I'm doing wrong. and I'm not even sure that is the right way to capture smpp packets. Can someone help me please?
Related
Here is my setup: On my home network a server is running on port SERVER_PORT. A port forwarding rule has been added to the router such that all incoming connections to SERVER_PORT will reach the server's machine. Somewhere else on the internet there exists a client who tries to send a UDP packet to the server and receive a packet back.
The server will receive the connection on SERVER_PORT but will send a packet back from a socket bound to a different (random) port.
The idea is emulating a listener socket just like the one used for TCP, and for each new connection allocating a new socket.
I have tested my program with clients that are connected to my home network, and outside the home network (cellular). The program didn't work either way.
The program does work though if I send a packet back using the server's original socket (the one that is bound to SERVER_PORT).
I am assuming this has something to do with my router's NAT table but I can't quite figure out the details.
My question is how can a packet be sent back from a different socket, other than the one that had been used for previous packets, and would I have had the same issue if the server was directly connected to the internet?
I wrote a small java program to demonstrate the issue:
Here is the server's code:
//create both sockets and a buffer
DatagramSocket serverSocket1 = new DatagramSocket(SERVER_PORT);
DatagramSocket serverSocket2 = new DatagramSocket();
byte[] buffer = new byte[512];
//receive a packet from serverSocket1
DatagramPacket packet1 = new DatagramPacket(buffer, buffer.length);
serverSocket1.receive(packet1);
System.out.println("received packet from: address = " + packet1.getAddress() + ", port = "+ packet1.getPort());
//send a packet from serverSocket2
DatagramPacket packet2 = new DatagramPacket(buffer, buffer.length, packet1.getAddress(), packet1.getPort());
serverSocket2.send(packet2);
System.out.println("sent packet back");
Here is the client's code: (note: SERVER_ADDRESS is set to my public ip)
//create a socket for the client and a buffer
DatagramSocket clientSocket = new DatagramSocket();
byte[] buffer = new byte[512];
//send packet1
DatagramPacket clientPacket1 = new DatagramPacket(buffer, 0, buffer.length, InetAddress.getByName(Server.SERVER_ADDRESS), Server.SERVER_PORT);
clientSocket.send(clientPacket1);
System.out.println("sent packet");
//receive packet2
DatagramPacket clientPacket2 = new DatagramPacket(buffer, buffer.length);
clientSocket.receive(clientPacket2);
System.out.println("received packet from: address = " + clientPacket2.getAddress() + ", port = "+ clientPacket2.getPort());
After running first the server and the the client I get the following output:
server:
received packet from: address = /107.107.56.147, port = 29098
sent packet back
client:
sent packet
My app is unable to receive the UDP packets when running in the emulator. UDP packets are sent by below java program on "localhost" over the port 49999.
DatagramSocket clientsocket;
DatagramPacket dp;
BufferedReader br;
InetAddress ia;
byte buf[] = new byte[1024];
int cport = 50000, sport = 49999;
clientsocket = new DatagramSocket(cport);
dp = new DatagramPacket(buf, buf.length);
br = new BufferedReader(new InputStreamReader(System.in));
ia = InetAddress.getLocalHost();
while(true)
{
Random rand = new Random();
String str1 = rand.nextInt(100) + "";
buf = str1.getBytes();
System.out.println("Sending " + str1);
clientsocket.send(new DatagramPacket(buf,str1.length(), ia, sport));
try{
Thread.sleep(100);
} catch(Exception e){}
}
Another java UDP server program running on the same localhost receives the packets fine. This means that the packets are sent to localhost:49999 correctly.
To forward the packets from localhost to the emulator, I did telnet redirect as below:
telnet localhost 49999
redir add udp:49999:49999
The UDP receiver in the app looks like this:
byte[] data = new byte[1400];
DatagramPacket packet = new DatagramPacket(data, 1400);
DatagramSocket socket = new DatagramSocket(49999);
socket.setSoTimeout(200);
try{
socket.receive(packet); ---->> This throws a SocketTimeoutException
} catch(SocketTimeoutException e){}
My understanding was that the telnet redirect should take care of forwarding the packets from my development machine's localhost:49999 to emulator's localhost:49999 so that the data is available on the DatagramSocket(49999). However it keeps throwing the SocketTimeoutException all the time.
It would be a great help to know what is the missing piece of the puzzle here.
After connecting to the localhost you may want to check that the port was actually asigned as intended with the command netstat -na in the cmd. It also might be worth a try to use the IP 127.0.0.1 instead.
I have made a UDP server. It is working well but the problem is, It only accepts the client request once and gives response but on sending the 2nd request it does not replies to the client and also doesnot receives the message.
Here is my code....... I am unable to troubleshoot this
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket socket = new DatagramSocket(SERVERPORT,
serverAddr);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
updatetrack("Server: Receiving\n");
socket.receive(packet);
updatetrack("Server: Message received: '"
+ new String(packet.getData()) + "'\n");
updatetrack("Server: Succeed!\n");
updatetrack("I want to send the data to you .......");
byte[] sbuff;
sbuff = ("opSERVERSTARTED").getBytes();
socket.send(new DatagramPacket(sbuff, sbuff.length, packet
.getAddress(), packet.getPort()));
Your code implies that you only want to receive one packet.
If you want to receive more packets, you have to do that in a loop and handle the runtime of the loop by a defined stop criteria.
socket.receive(packet); I think this code must be in a while loop, so it can accept more than one client. Something like this:
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket socket = new DatagramSocket(SERVERPORT,
serverAddr);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
while (someCondition) {
updatetrack("Server: Receiving\n");
socket.receive(packet);
updatetrack("Server: Message received: '"
+ new String(packet.getData()) + "'\n");
updatetrack("Server: Succeed!\n");
updatetrack("I want to send the data to you .......");
byte[] sbuff;
sbuff = ("opSERVERSTARTED").getBytes();
socket.send(new DatagramPacket(sbuff, sbuff.length, packet
.getAddress(), packet.getPort()));
}
I am not sure about the end of the curly brackets, I am not familiar with UDP server. You can move it to where the repeating code ends. Hope this helps!
This is my udp_broadcast server code where iam listening on 0.0.0.0
try{
socket = new DatagramSocket (7777,InetAddress.getByName("0.0.0.0"));
socket.setBroadcast(true);
while(true)
{
System.out.println(getClass().getName()+"ready recieve broadcast packets!");
//recieve a packet
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf,recvBuf.length);
socket.receive(packet);
System.out.println(getClass().getName() +"packet recieved from :" +packet.getAddress().getHostAddress());
System.out.println("data is "+new String(packet.getData()));
String message = new String(packet.getData()).trim();
if(message.equals("p2p_project_node"))
{
byte [] senddata = "I_found_you_did_YOU".getBytes();
DatagramPacket sendpacket= new DatagramPacket(senddata,senddata.length,packet.getAddress(),packet.getPort());
socket.send(sendpacket);
System.out.println("packet sent to "+sendpacket.getAddress().getHostAddress());
}
}
}
on client side iam broadcasting packet 255.255.255.255 so that i get a reply from server
eventually and i endup in getting server ip address
udp_client_side code
try {
c = new DatagramSocket();
c.setBroadcast(true);
byte [] sendData = "p2p_project_node".getBytes();
//this is broadcasting to 255.255.255.255a
try{
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,InetAddress.getByName("255.255.255.255"),7777);
c.send(sendPacket);
System.out.println("rewuest sent to 255.255.255.255");
}
catch(Exception e) {
System.out.println("exception 255.255" +e);
}
on the server side iam getting error saying that
Exception java.net.BindException "Address already in use :cannot bind"
where am i going wrong if someone could help me it would be great Thanks in advance
The address is already in use. You cannot bind your socket to that address. Some other process already has a UDP socket bound to that poet. Possibly a previous instance of your own program.
Don't broadcast to 255.255.255.255. It was deprecated twenty years ago. Use the subnet broadcast address, or better still use multicast.
You can bind your socket to that port, if this port is occupied by a previous instance of your own program. You need to use "reuse" parameter in all instances of your program. Call .setReuseAddress(true); before binding.
Where can I find details on UDP in Java and how is a basic UDP communcation established?
This page provides detailed information on how to create a UPD server and client.
In essence, you create a server like this:
// Setup the socket
DatagramSocket socket = new DatagramSocket(12345);
// Receive a packet
byte[] buffer = new byte[512];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
// Do something with the data in the buffer
// and if necessary receive more packets
// Close the socket
socket.close();
On the client side, you can then send a packet like this:
// Create a socket
DatagramSocket socket = new DatagramSocket();
// Create a buffer and fill it with your data
byte[] buffer = new byte[512];
...
// Send the packet
InetAddress address = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, 12345);
socket.send(packet);
// Close the socket
socket.close();