I try to send and receive UDP packets continuously between an Android app and a server.
Is there any way to make that happen ?
My current networking code (running in a Thread) is shown bellow. The client is connected through 3G. The port configured client side is 1088.
The server just echo the packet to the client when received.
The server receive the packet correctly from the client but the client doesn't receive anything back.
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Log.d(TAG, "S: Connecting...");
DatagramSocket socket = new DatagramSocket();
DatagramSocket receive_socket = new DatagramSocket(SERVERPORT, InetAddress.getByName("0.0.0.0"));
while(running) {
DatagramPacket packet_send = new DatagramPacket(msg, msg.length, serverAddr, SERVERPORT);
Log.d(TAG, "C: Sending: '" + new String(msg) + "'");
socket.send(packet_send);
// Prepare a UDP-Packet that can contain the data we want to receive
DatagramPacket packet = new DatagramPacket(buf, buf.length);
Log.d(TAG, "S: Receiving...");
// Receive the UDP-Packet
receive_socket.receive(packet);
Log.d(TAG, "S: Received: '" + new String(packet.getData()) + "'");
synchronized (this) {
wait(500);
}
}
I suspect the 3G connection is NATed (the server reports a port different from 1088).
If so, is there anything I can do to overcome that ?
Or is there anything wrong I do in my code ?
Turned out the code was working fine, the 3G service provider was blocking some UDP packets.
Related
I am developing an Android multiplayer game using Wi-Fi direct.
Using Wi-Fi direct, I am able to establish connection between peer devices. Also the code is able to send the data from client device to server device. (According to Android documentation, the Wi-Fi direct uses client-server model)
Problem:
I am not able to share the data from server device to client device using Wi-Fi direct.
I have following questions:
Is there any other way to transfer data (bi-directional) between two
Android devices which are connected through Wi-Fi Direct?
During my online research I understood that to send data from server
device to client device, server needs to know the client’s IP
address. How to use this client’s IP address to send data from
server device to client device? (I am able to fetch the client’s IP
address)
I'd appreciate any suggestions on these queries. Thank you in advance.
Code:
Server Side
public class DataTransferAsyncTask extends AsyncTask<Void,Void,String>{
ServerSocket serverSocket;
Socket client;
InputStream inputstream;
Context context = mActivity.getApplicationContext();
String s;
InetAddress client_add;
#Override
protected String doInBackground(Void... voids) {
try{
serverSocket = new ServerSocket(9999);
Log.e("hello", "Server: Socket opened");
client = serverSocket.accept();
Log.e("hello", "Server: connection done");
inputstream = client.getInputStream();
// OutputStream outputStream = serverSocket.getO
//getting data from client
byte[] address = new byte[12];
if(client.isConnected())
inputstream.read(address);
s = new String(address);
String only_add = new String();
only_add = s.substring(0,12);
client_add = InetAddress.getByName(only_add);
Log.e("hello", "Server: clients ip 1 " + only_add);
Log.e("hello", "Server: converted address 1 " + client_add + " \n is connected"+
client.isConnected());
//send data to client
OutputStream stream = client.getOutputStream();
stream.write(s.getBytes());
Log.e("hello","context value "+context);
// cancel(true);
}catch (IOException e){
}
return null;
}
}
Client Side:
#override
protected void onHandleIntent(Intent intent) {
Log.e("hello","client socket");
Toast.makeText(this,"client socket",Toast.LENGTH_LONG).show();
Context context = getApplicationContext();
if(intent.getAction().equals(action_send_data)){
String host = intent.getStringExtra(group_owner_address);
Socket socket = new Socket();
int port = intent.getIntExtra(group_owner_port,9999);
//binding connection
try{
String x="hello";
Log.e("hello","opening client socket");
byte[] address = getLocalAddress();
String ipAdd = getDottedDecimalIP(address);
socket.bind(null);
socket.connect(new InetSocketAddress(host,port),socket_timeout);
Log.e("hello","device socket address "+ socket.getInetAddress() );
Log.e("hello","client socket is connected"+socket.isConnected());
Log.e("hello","device address :"+ipAdd + " byte "+ address);
//sending data to server
OutputStream stream = socket.getOutputStream();
stream.write(ipAdd.getBytes());
//getting data from the server(supposed to)
InputStream inputstream = socket.getInputStream();
byte[] address_to_sto_fr_ser = new byte[15] ;
inputstream.read(address_to_sto_fr_ser);
String s = new String(address_to_sto_fr_ser);
Log.e("msg from server","msg from server "+s);
// stream.close();
// is.close();
}catch (IOException e){
}
}
}
The communication between client and WiFi Direct Group Owner is based on Socket server running on the Group Owner and clients connected to that server.
Once WiFi Direct group is formed(you can know that by checking "onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo)"), check if the current device is the Group Owner and if so, start the sockets server (similar to your code):
mServerSocket = new ServerSocket(mPort);
Log.e(getClass().getSimpleName(), "Running on port: " + mServerSocket.getLocalPort());
Then next, add this line to accept connections and store a reference of the client socket:
Socket mSocket = mServerSocket.accept();
Now, you have a reference of the client socket, you can use it to send data / messages to it. Next, the other device (client) should initiate a connection to the socket server:
mSocket = new Socket();
mSocket.bind(null);
mSocket.connect(new InetSocketAddress(mAddress, mPort), 500);
To send message from server to client:
DataOutputStream mDataOutputStream = new DataOutputStream(mSocket.getOutputStream());
Send simple message:
mDataOutputStream.writeUTF(message);
mDataOutputStream.flush();
Hope this helps.
I have built a client-server application in Android(Compiling with java-6) to send and receive udp packets.
My client code is as follow:
DatagramSocket socket =new DatagramSocket();
socket.setBroadcast(true);
DatagramPacket packet = new DatagramPacket(dgram, dgramLength, host, port);
socket.send( packet );
socket.close();
My server code is as follows:
DatagramSocket socket =new DatagramSocket(this.port);
byte[] data=new byte[512];
DatagramPacket packet = new DatagramPacket(data, data.length) ;
// Wait for a response from the server
try
{
socket.receive(packet) ;
}
catch (Exception e)
{}
The issue that I am facing is that when I am working on a wired network then all the sent packets are being received by master properly but when I am running the same code over wifi then sometimes sent packets are being received and sometimes not. I want to know that whether it is the general behavior of a wifi network or not.
Any kind of help is appreciated.
I am trying to connect to a datalink that sends UDP packet. These packets are not 'broadcasted.' (I understand that there is two ways to send a UDP backet, to broadcast such that any machine can receive on the network, or to send to a specific IP...my understanding is limited to this, but I know that they are sent to a specific IP).
I am unable to receive the packets on my Android app I am testing with (Galaxy S3...internet permission has been enabled in the Manifest). I am binding to the host machine (IP) and its associated port. The packet traffic is seen in WireShark.
Here is my code. Anything glaring I am omitting?
try {
Log.d("UDP", "1");
DatagramSocket serverSocket = new DatagramSocket();
Log.d("UDP", "2");
InetAddress address = InetAddress.getByName(UDP_IP);
Log.d("UDP", "2a");
serverSocket.connect(address, UDP_SERVER_PORT);
Log.d("UDP", "2b");
serverSocket.setSoTimeout(5000); //5 sec wait for the client to connect
Log.d("UDP", "3");
byte[] data = new byte[1024];
Log.d("UDP", "4");
DatagramPacket packet = new DatagramPacket(data, data.length);
Log.d("UDP", "5");
Log.d("UDP", "S: Receiving...");
serverSocket.receive(packet);
//lock.release();
retVar = 1;
Log.d(" Received Packet", "Good");
}
catch (Exception e) {
Log.e("UDP", "S: Error", e);
}
I am doing application which send some data from mobile phone to PC. Im using socket to do it. When the server is online it works, but when I try to connect with wrong ip/port or server is not running then application freezes and I cant do nothing. It because client on mobile phone tries to connect to server.
I have main class in which I make:
Thread cThread = new Thread( new TCPClient( ip, port, message, context) );
cThread.start();
There is context in new TCPClient because i need to make Toast when message is sent or when error appears. In TCPClient class there is:
public void run(){
try {
InetAddress serverAddr = InetAddress.getByName(s_ip);
Log.d("TCP", "C: Connecting...");
Socket socket = new Socket(serverAddr, s_port);
When server is online it goes to:
Log.d("TCP", "C: Sending: '" + s_msg + "'");
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
out.println(s_msg);
Log.d("TCP", "C: Sent.");
Log.d("TCP", "C: Done.");
but when the server is offline or I put wrong ip/port my application freezes. I cant do nothing for a while.
Is there any solution to force stop trying connect to server after some time? For example after 5 second application will go to catch and give me error.
I tried to do this with AsyncTask, then application is working even when Client tries to connect to server, but toast with error appears after not acceptable time for me, so I would like a solution which will give me error when client cannot connect with server in for example 5 seconds.
You can set the connection timeout. You have to use different constructor of Socket class. Insead of:
Socket socket = new Socket(serverAddr, s_port);
use:
Socket socket = new Socket();
socket.connect(new InetSocketAddress(serverAddr, s_port), 5000);
In case of timeout an exception is thrown.
Perhaps you didn't set a timeout connection so it's "0" by default which means that it will never timeout , so you can set the timeout to 1 minute it won't freeze for more than one minute .
I am able to connect to TCP IP netwrok but even if i am sending some
byte array but yet i am not seeing any output on Server console.
Server is C++ and i need to send data from my android apps. I am able
to connect but when i send data i am not getting any notification. the
followins is my code.
InetAddress serverAddr = InetAddress.getByName(serverIP);
SocketAddress socketadd= new InetSocketAddress(serverAddr, serverPort);
Log.d("TCP", "C: Connecting...");
//Socket socket = new Socket(serverAddr, serverPort);
Socket socket=new Socket();
try {
Log.d("TCP", "C: Sending: '" + msg + "'");
socket.connect(socketadd);
Log.e("Connect:", "Connect:");
DataOutputStream dataout = new
DataOutputStream(socket.getOutputStream());
dataout.flush();
byte haeader[]=new byte[6];
// String data="20110110,cswxerotest,cswxerotest";
// Packet p=new Packet();
//byte bdata[]=converttoCPP(getBytes());
byte bdata[]=getBytes();
//byte a[]=new byte[20];
//dataout.writeByte(5);
dataout.write(bdata,0,bdata.length);
dataout.flush();
I see you have a message msg to send, but I don't see that you convert it to bytes and send it anywhere (something like byte bdata[] = msg.getBytes() )