Im a newbie in this so please escuse me if i ask dumb questions.
Im trying to make a UDP connection between Eclipse's PC Emulator & a android phone
(or between two android phone devices).
I have a router and the phone connects to the internet thru router's wifi network. The PC is on same network also (direct cable router-PC connection). Im trying to send some text data from Server thread to Client thread but nothing is received/sent. :(
The Server java class (RE-EDITED, Server receives msg. from Client):
public class server implements Runnable
{
// the Server's Port
public static final int SERVERPORT = 6000;
// running Server thread.
public void run()
{
Log.d("redwing","server thread started.");
DatagramSocket serverSocket = null;
try
{
// Open Server Port
serverSocket = new DatagramSocket(server.SERVERPORT);
byte[] receiveData = new byte[32];
byte[] sendData = new byte[32];
// loop until "server_finished" becomes False.
while(createserver.server_finished)
{
if(renderer.gGL!=null) // ignore me, just a null pointer checker
{
// waiting for the incoming client's message packet
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
renderer.recv = new String(receivePacket.getData());
Log.d("server","packet received from client, ETA " + timing.getNow() + " " + renderer.recv); // timing getNow - just returns current system minute & second.
// server is replying to the client back with a message.
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
sendData = new String("server msg").getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
renderer.sent = new String(sendData, 0, sendData.length);
Log.d("server","packet sent to client, ETA " + timing.getNow() + " " + renderer.sent); // timing getNow - just returns current system minute & second.
}
}
// close the socket
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
catch (Exception e)
{
Log.e("server", "Error", e);
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
finally
{
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
Log.d("redwing","server thread terminated.");
}
}
and the Client java class (RE-EDITED, Client does not receive msg from Server) :
public class client implements Runnable
{
public static final int CLIENTPORT = 5000;
// running Client thread.
public void run()
{
Log.d("redwing","client thread started.");
DatagramSocket clientSocket = null;
try
{
// getting local address
clientSocket = new DatagramSocket(server.SERVERPORT);
InetAddress IPAddress = InetAddress.getByName("192.168.0.100");
// displaying IP & hostname.
Log.d("client", "IP: " + IPAddress.getHostAddress() + " Name: " + IPAddress.getHostName());
byte[] sendData = new byte[32];
byte[] receiveData = new byte[32];
// Loop until client_finished becomes False.
while(createclient.client_finished)
{
if(renderer.gGL!=null) // ignore me, just a null pointer checker
{
// sending a message to the server
sendData = timing.getNow().getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, client.CLIENTPORT);
clientSocket.send(sendPacket);
renderer.sent = new String(sendData,0,sendData.length);;
Log.d("client","packet sent to server, ETA " + timing.getNow());
// waiting for the server packet message.
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
renderer.recv = new String(receivePacket.getData());
Log.d("client","packet received from server, ETA " + timing.getNow());
}
}
// close the socket
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
catch (Exception e)
{
Log.e("client", "Error", e);
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
finally
{
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
Log.d("redwing","client thread terminated.");
}
}
the Permisions are enabled in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<user-permission android:name="android.permission.NETWORK" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
I'm running the Server on the android PC Emulator, and the Client on my android Phone.
Both Client & Server threads run just fine but ... the problem is that i dont get any data exchanged between them. The client doesn't receive anyting and the server doesnt receive anything. The packets are sent but nothing received .
What im doing wrong ?
Please help me.
Thank you in advance.
After running your emulator, type it in command prompt - "telnet localhost ", then type "redir add udp:5000:6000". Connect client with port number 5000 and open udp server with port number 6000. Then you can receive client message from udp server.
Take a look for details
clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("<pc ip>"); // instead of "localhost"
public static final String SERVERIP = "127.0.0.1"; // 'Within' the emulator!
public static final int SERVERPORT = 6000;
/* Retrieve the ServerName */
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket socket = new DatagramSocket(SERVERPORT, serverAddr);
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 am working on a client/server project, the client being Android and the server being C#.
What I am trying to do is the Android app listens on a UDP socket and the C# server sends a message on that port. Android will then receive the message from the reply, and send back a response.
This is the code I have:
public void run()
{
Log.d(TAG, "Heartbeat manager thread starting");
try
{
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
DatagramSocket socket = new DatagramSocket(HEARTBEAT_PORT);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (!cancelThread)
{
socket.receive(packet);
final String xml = new String(packet.getData(), 0, packet.getLength());
Log.v(TAG, xml);
XmlSettings xmlSettings = new XmlSettings();
xmlSettings.setIndent(true);
XmlWriter writer = new XmlWriter(xmlSettings);
writer.writeStartDocument();
writer.writeStartElement("HeartbeatManager");
writer.writeElementString("Command", Defines.ServerCommands.HeartbeatResponse.toString());
writer.writeEndElement();
buffer = writer.returnXmlOutput().getBytes();
DatagramPacket replyPacket = new DatagramPacket(buffer, buffer.length);
socket.send(replyPacket);
}
}
catch (SocketException ex)
{
Log.e(TAG, "Socket Exception Occurred: " + ex.toString());
}
catch (IOException ex)
{
Log.e(TAG, "IOException Occurred: " + ex.toString());
}
At the moment it throws an exception when I do the socket.send stating that the destination address is null.
You must set the destination address in the DatagramPacket before sending it.
The constructor you're using (without the address) is just for receiving, not for sending.
In UDP protocol, destination is set in the packet because there is not a connection (like TCP)
So in your code you are telling the socket, which has no concecpt of destination to send a packet without destination, so it'll throw and exception.
InetSocketAddress address = InetSocketAddress("www.google.com", 8080);
DatagramPacket replyPacket = new DatagramPacket(buffer, buffer.length, address);
socket.send(replyPacket);
I saw many pages, and try many advices, but still can't receive data via UDP on device (nexus 4). I work in my LAN, over wifi (3G is off).
I have a client, on PC (192.168.1.5) and consumer on Android device (192.168.1.3:54445)
Here is a client code:
String string = "hello udp";
DatagramSocket socket = null;
try {
address = InetAddress.getByName("192.168.1.3");
socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 54445);
socket.send(packet);
Here is a consumer code:
DatagramSocket socket = null;
stop = false;
InetAddress address = null;
try {
socket = new DatagramSocket(54445);
while (!stop) {
byte[] buffer = new byte[minBufSize];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
Log.d(this.getClass().getSimpleName(), String.valueOf(packet.getLength()));
Debugger stop on socket.receive(packet). Consumer work in AsyncTask.
Thank you!
It's my fault, at first check you router settings.
I'm trying to send a simple string from an android device to a pc.
I managed to send the string via wifi (because is on a LAN network), but the code doesn't work over 3g.
The code i'm using is this:
class send extends AsyncTask
{
#Override
protected Object doInBackground(Object... params) {
try {
InetAddress serverAddr = InetAddress.getByName("IP here")
Socket socket = new Socket(serverAddr, 8564);
String message = "sample_message";
try {
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
out.println(message);
} catch(Exception e) {}
finally {
socket.close();
}
} catch (Exception e) {}
return null;
}
}
Where is your PC connected? Is it a LAN behind NAT? Are you using the LAN IP address as serverAddr? What is "IP here"?
If you are using a local network IP address behind the NAT you'll never be able to connect.
If you have a router/wifi AP, enable port forwarding to you PC and use the public IP address provided by the ISP as serverAddr.
Have you tried creating a DataOutputStream like
DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
dos.writeBytes(message + '\n');
Instead of :
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
out.println(message);
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.