I am working on a program which needs to figure out if remote SIP UDP port 5060 is reachable from client machine.
As there is no direct method to check the availability of UDP port. I want to create a simple java class which will send the OPTIONS message to SIP UDP server and then the server will reply back to client in java.
Any help/ direction will be great help!
Thanks,
Anupam
Thanks for your response, I tried below piece of code but it did not get any reply from server:
String message = "OPTIONS sip:opensips#host;transport=udp SIP/2.0\r\nCall-ID: 7df5e96c6b1b98af25ad6c7845d48f5d#49.249.132.30\r\nCSeq: 1 OPTIONS\r\nFrom: \"Anupam\" <sip:Anupam#localhost:5080>;tag=textclientv1.0\r\nTo: \"opensips\" <sip:opensips#host>\r\nVia: SIP/2.0/UDP 49.249.132.30:5080;branch=z9hG4bK-3938-f66aaa8dda2fe3b863b4acde5fbcab67\r\nMax-Forwards: 70\r\nContact: \"Anupam\" <sip:Anupam#localhost:5080>\r\nContent-Length: 0\r\n\r\n";
System.out.println("Message is "+ message);
byte [] data = message.getBytes();
DatagramPacket packet = new DatagramPacket( data, data.length, host, port ) ;
But it didn't work.
To do this by the book (compliant with RFC 3261), you will either need to create quite a bit of machinery to handle retransmissions, etc., or to use a library like JAIN-SIP.
However, you may be able to get most of the way there by simply opening a UDP socket, sending a String containing an appropriately-formatted OPTIONS message over the socket, and then waiting a while to see if you get a SIP response on that socket. Any old SIP response (success or error) will verify that the server is reachable.
Here is an example OPTIONS message from the RFC:
OPTIONS sip:carol#chicago.com SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKhjhs8ass877
Max-Forwards: 70
To: <sip:carol#chicago.com>
From: Alice <sip:alice#atlanta.com>;tag=1928301774
Call-ID: a84b4c76e66710
CSeq: 63104 OPTIONS
Contact: <sip:alice#pc33.atlanta.com>
Accept: application/sdp
Content-Length: 0
In order to check remote side UDP sip service availability using REGISTER method you can use the following code.
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Random;
public class CheckSipUdp{
//Check remote SIP service availability
public void checkSipUdp(String ipAddress, int outPort)throws Exception{
DatagramSocket sipSocket = new DatagramSocket(0);
sipSocket.setSoTimeout(1000);
InetAddress inetIpAddress = InetAddress.getByName(ipAddress);
byte [] sendData = new byte[1024];
byte [] receiveData = new byte[1024];
//Message/Method which will be used for checking remote server availability.
String method = "REGISTER sip:" + ipAddress + ":" + outPort + " SIP/2.0\r\nCall-ID: " + generateCallId() + "#" + InetAddress.getLocalHost().getHostAddress() +"\r\nCSeq: 1 REGISTER\r\nFrom: <sip:" + InetAddress.getLocalHost().getHostAddress() + ":" + sipSocket.getLocalPort() + ">;tag=" + new Random().nextInt() + "\r\nTo: <sip:alice#" + ipAddress + ":" + outPort + ">\r\nVia: SIP/2.0/UDP " + InetAddress.getLocalHost().getHostAddress() + ":" + sipSocket.getLocalPort() + ";branch=z9hG4bK-323032-" + generateCallId() + "\r\nMax-Forwards: 70\r\nContact: <sip:" + InetAddress.getLocalHost().getHostAddress()+ ":" + sipSocket.getLocalPort() + ">\r\nContent-Length: 0\r\n\r\n";
sendData = method.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, inetIpAddress, 5060);
sipSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
sipSocket.receive(receivePacket);
String response = new String(receivePacket.getData());
System.out.println(ipAddress + "\n" + response);
sipSocket.close();
}
//Generating unique callID
public static String generateCallId(){
Random r = new Random();
long l1 = r.nextLong() * r.nextLong();
long l2 = r.nextLong() * r.nextLong();
return Long.toHexString(l1) + Long.toHexString(l2);
}
public static void main(String [] args) throws Exception{
CheckSipUdp sip = new CheckSipUdp();
sip.checkSipUdp(args[0], Integer.parseInt(args[1]));
}
}
Related
I have a client and server, I can send data to the server but I need help on how I can use the data received from the client to draw a graph using Plot2DPanel/JMathPlot. a simple code on how I can assign data received from the client to Plot2DPanel. I have the code below, which receives data from the client but I don't how can I use this on Plot2DPanel.
while(true){
System.out.println("Waiting for the incoming mesages" +portNumber+ "....");
receiveSocket.receive(receivedPacket);
IAddress address = receivedPacket.getAddress();
int clientPort = receivedPacket.getPort();
String message = new String(receivedPacket.getData());
message = message.trim();
System.out.println("The message {+mesage+}.\n\t\t The message is received from host: " +IAddress+ "on port" + portNumber);
byte[] sendData = new byte[256];
String sendBackMessage = "Thank you, message was received";
sendData = sendBackMessage.getBytes();
receivedPacket = new DatagramPacket(sendData, sendData.length, IAddress, clientPort);
receiveSocket.send(receivedPacket);
I've wrote simple client (using SocketChannel):
User friend = database.getUserByName("jonh");
SocketChannel friendSkt = SocketChannel.open(new InetSocketAddress(InetAddress.getByName(friend.getHost()), friend.getPort()));
System.out.println("Local: " + friendSkt.socket().getLocalSocketAddress()
+ " |Remote: "+ friendSkt.socket().getRemoteSocketAddress());
and server (using simple Socket):
ServerSocket skt = new ServerSocket(0);
Socket server = skt.accept();
InputStream x = server.getInputStream();
System.out.println("Local: " + server.getLocalSocketAddress() + " |Remote: "+ server.getRemoteSocketAddress());
Even if connect returns no exception and client write on socket (simple getOutputStream.write(...)), server not read and returns -1. So I've printed the address of each socket and found this:
CLIENT: Local: /192.168.0.2:58981 |Remote: /192.168.0.2:58968
SERVER: Local: /192.168.0.2:58968 |Remote: /192.168.0.2:58980
It is normal that client local port is server remote port+1 instead to being the same value?
How can broadcast a message from single server to multiple clients and listen for a reply from one of the clients.
I used Multicast Programming to broadcast the message to the clients. And If i send the message from one of my clients back to the server either through TCP or UDP, I am getting a "java.net.ConnectException: Connection refused: connect" exception.
Please help me out.
Thanks in Advance.
Sender Code :
// Broadcasting the message
msg = "This is multicast! " + counter;
counter++;
outBuf = msg.getBytes();
// Send to multicast IP address and port
InetAddress address = InetAddress.getByName("224.2.2.3");
outPacket = new DatagramPacket(outBuf, outBuf.length, address,
PORT);
socket.send(outPacket);
System.out.println("Server sends : " + msg);
socket.close();
// Receiving TCP
apSock = new Socket("131.151.88.165", 6161);
apBuffReader = new BufferedReader(new InputStreamReader(
apSock.getInputStream()));
while ((ap2Toap1 = apBuffReader.readLine()) != null) {
System.out.println(ap2Toap1);
}
Receiver Code :
count++;
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
String msg = new String(inBuf, 0, inPacket.getLength());
System.out.println("From " + inPacket.getAddress() + " Msg : "
+ msg);
socket.close();
// Sending TCP
apSock = new Socket("131.151.88.165", 6161);
System.out.println("Hello2");
respWriter = new PrintWriter(apSock.getOutputStream());
System.out.println("Writing back to the server");
respWriter.println(outBuf);
if (respWriter != null)
respWriter.close();
There is no listening in your code. TCP listening in Java is accomplished via a ServerSocket. You aren't using one. Instead you're using Sockets at both ends. So what you have is two clients and no server. No communication is possible between two TCP clients.
As stated in my title, I'm trying to build a very simple file transfer service in java. Right now, all I have been able to do in construct a simple client/server that can send and receive strings of text. Here is the code:
UDPClient.java:
import java.io.*;
import java.net.*;
class UDPClient {
public static void main(String args[]) throws Exception
{
BufferedReader inFromUser =
new BufferedReader(new InputStreamReader
(System.in));
DatagramSocket clientSocket = new DatagramSocket();//port # is assigned by OS to the client
InetAddress IPAddress =
InetAddress.getByName("localhost");
byte[] receiveData = new byte[1024];
String sentence = inFromUser.readLine();
byte[] sendData = sentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length,
IPAddress, 7777); //data with server's IP and server's port #
clientSocket.send(sendPacket);
DatagramPacket receivePacket =
new DatagramPacket(receiveData,
receiveData.length);
clientSocket.setSoTimeout(1000);
clientSocket.receive(receivePacket);
// we still need to catch the exception and retry
String modifiedSentence =
new String(receivePacket.getData(),
0,
receivePacket.getLength());
System.out.println("FROM SERVER:" +
modifiedSentence);
clientSocket.close();
}
}
UDPServer.java
import java.io.*;
import java.net.*;
class UDPServer {
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new
DatagramSocket(7777); //server will run on port #9876
byte[] receiveData = new byte[1024];
while(true)
{
DatagramPacket receivePacket =
new DatagramPacket(receiveData,
receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(
receivePacket.getData(),
0,
receivePacket.getLength());
InetAddress IPAddress =
receivePacket.getAddress(); //get client's IP
int port = receivePacket.getPort(); //get client's port #
System.out.println("client's port # =" + port);
System.out.println("client'sIP =" +IPAddress);
System.out.println("client's message =" +sentence);
String capitalizedSentence =
sentence.toUpperCase();
byte[] sendData = capitalizedSentence.
getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData,
sendData.length,
IPAddress, port);
serverSocket.send(sendPacket);
}
}
}
Ultimately what I'd like to do is send a file path to the server, have the server return the file, and then save it to a predetermined location like C:\Desktop\Folder.
I'm really at a loss for how to advance past where I am, so any advice, pointers, or resources that you could share would be great. I'm very new at this and feeling way out of my depth.
Thanks!
Unlike TCP UDP uses a non-persistent connection. Therefore, you will have to maintain state in the request and response packets.
For example, the request packet could look as follows.
2 bytes - File name length
(variable) - File name 4 bytes - Start position
4 bytes - Seq. no.
4 bytes - Max chunk size
Server will read upto 'Max chunk size' bytes from 'Start position' and return to client in following format. The Seq. no. will be echoed back from request so client can relate request with response.
1 byte - Response code
4 byte - Seq. no.
4 bytes - Payload length
(variable) - Payload
I am implementing a really basic server-client model in Java, by using UDP sockets and I have come across a really strange issue.
All I want to do is let the user (client) send a message to the server and then the server will print it.
I have an example but I am missing something since I have the following issue:
If the client sends the message "a" to the server it gets received correctly.
If the client sends the message "bbb" to the server it gets received correctly.
If the client sends the message "c" to the server, then the server will print "cbb" as the received message.
It seems as if the server does clean some kind of buffer when it gets a new message.
This is the code I am using:
Server
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
public static void main(String args[]) throws Exception {
byte[] receive_data = new byte[256];
int recv_port;
DatagramSocket server_socket = new DatagramSocket(5000);
System.out.println("Server - Initialized server. Waiting for client on port 5000");
while (true) {
// System.out.println("Server - Listening for connections...");
DatagramPacket receive_packet = new DatagramPacket(receive_data, receive_data.length);
server_socket.receive(receive_packet);
String data = new String(receive_packet.getData());
InetAddress IPAddress = receive_packet.getAddress();
recv_port = receive_packet.getPort();
if (data.equals("q") || data.equals("Q")) {
System.out.println("Server - Exiting !");
break;
} else {
System.out.println("Server - Client from IP " + IPAddress + " # port " + recv_port + " said : " + data + " (length: " + receive_packet.getLength() + ")");
}
}
}
}
Client
public class UDPClient {
public static void main(String args[]) throws Exception {
byte[] send_data = new byte[256];
BufferedReader infromuser = new BufferedReader(new InputStreamReader(System.in));
DatagramSocket client_socket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
System.out.println("Client - Initialized the client...");
while (true) {
System.out.print("Client - Type Something (q or Q to quit): ");
String data = infromuser.readLine();
if (data.equals("q") || data.equals("Q")) {
System.out.println("Client - Exited !");
DatagramPacket send_packet = new DatagramPacket(send_data, send_data.length, IPAddress, 5000);
System.out.println("Client - Sending data : <" + data + ">");
client_socket.send(send_packet);
break;
} else {
send_data = data.getBytes();
DatagramPacket send_packet = new DatagramPacket(send_data, send_data.length, IPAddress, 5000);
System.out.println("Client - Sending data : <" + data + ">");
client_socket.send(send_packet);
}
}
client_socket.close();
}
}
I suppose that the mistake is something trivial, but my skills in network programming are limited, therefore I don't know what exactly it is.
Just to make clear, I am running both the server and the client at the same machine (mac) on different terminals, just in case it affects the situation in anyway.
Any help would be greatly appreciated.
EDIT
...And I come back to answer my own question.
The problem was that I was not defining the amount of data that the server socket should expect to read.
Therefore when I change
String data = new String(receive_packet.getData());
with
String data = new String(receive_packet.getData(), 0, receive_packet.getLength());
everything worked smoothly.
Just for future reference and for people who might come across the same problem :)
When you're constructing the String based on the result, you're currently ignoring the length of the received packet.
After using DataSocket.receive(DatagramPacket), the length of the DatagramPacket should be set to the length that was actually received:
The length field of the datagram packet object contains the length of
the received message. If the message is longer than the packet's
length, the message is truncated.
This should fix the problem on the receiving side:
String data = new String(receive_packet.getData(), 0, receive_packet.getLength());
For this to work you also need to make sure the data sent is of the right size. In particular, don't use send_data.length to construct the outgoing DatagramPacket. This will always use the full length of the buffer). The length parameter isn't meant to be always send_data.length (otherwise the constructor would get it itself from the array), it's meant for the actual useful length of the message within that array.
On your first call this is what receive_data looks like:
--------------
|"a"| | |
--------------
On your second call:
--------------
|"b"|"b"| "b" | notice that the "a" in data_receive was overwritten
--------------
On your third call, you only send a single letter,
so the only part of the array that gets overwritten is the first element:
--------------
|"c"|"b"| "b" |
--------------
This is happening because there is still data left in the receive_data array in between messages to the server, a simple way around this would to just initialize a new array inside of you receive loop. That way every time you receive a message you will have a fresh array waiting for you.
while (true)
{
byte[] receive_data = new byte[256];
......
}
To solve the problem you should use length of receive_packet to create a String or array.
For higher performance in server side, it's better to initialize receive_packet before while section and reset its length at the end of while section to reuse it in loop : receive_packet.setLength(buffer.length);