I'm new to Android programming and I'm trying to send some text data to PC via TCP.
I built an example I found on the web, which has an Android Client and a Java Server.
The server runs ok.
When I run the Android Client on the emulator or on the phone, both works perfectly well.
The problem is that I need it to communicate to a C# application, so I built an TCP server in C#.
Now, if I run the Client on the emulator it works and the C# server receive the data (a little messed, but it's probably an text encoding problem which I think won't be hard to solve). But anyway, the data is arriving at the c# server.
If I try to run the same Client on the phone I can't even connect to the C# server. I get a timeout error when connecting.
Also I can ping the PC from phone and ping the phone from PC, so I don't think it's a network problem.
I have some experience in C# but not much on sockets and even less on Android. So I ask, is there any difference on TCP protocols used by Java and C#? Sorry if it's a dumb question, but I googled it for hours and haven't found a clue.
Any ideas of what may be causing it?
The Java server code is this:
public class Servidor {
private static boolean executando = true;
private static String mensagem;
private static final int PORTA = 1234;
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(1234);
InetAddress addr = InetAddress.getLocalHost();
System.out.println("----------- SERVER CONNECTED "
+ addr.getHostAddress() + " PORT " + PORTA
+ " -----------");
System.out.println("Waiting connections.");
Socket socket = server.accept();
System.out.println("Server -> Connected Ip "
+ socket.getInetAddress().getHostAddress());
DataInputStream in = new DataInputStream(socket.getInputStream());
try {
while (executando) {
mensagem = in.readUTF();
System.out.println("Server-> Received Message: "
+ mensagem);
}
System.out.println("Servidor-> Finalizado.");
in.close();
socket.close();
server.close();
} catch (Exception e) {
System.err.println("Server -> Error: " + e.getMessage());
executando = false;
}
} catch (Exception e) {
e.printStackTrace();
}
} }
The C# Server code is this:
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
Console.WriteLine("\nStarting server...");
this.tcpListener = new TcpListener(IPAddress.Any, 1234);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
Console.WriteLine("\nWaiting for clients to connect...");
this.tcpListener.Start();
while (true)
{
blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
create a thread to handle communication
with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
Console.WriteLine("\nIncoming from client...");
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
a socket error has occured
break;
}
if (bytesRead == 0)
{
the client has disconnected from the server
break;
}
message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine("\nReceived: \n\n" + encoder.GetString(message, 0, bytesRead));
}
tcpClient.Close();
}
}
If needed, the Android Client code is exactly the one on the following link:
http://www.portalandroid.org/comunidade/viewtopic.php?f=7&t=11077&p=127577
Related
I have this simple tcp server class
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
this.tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 3000);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
Console.WriteLine("Hello");
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
Console.WriteLine("New connexion");
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
Console.WriteLine("Got Stream");
byte[] message = new byte[4096];
int bytesRead;
Console.WriteLine("Initializing..");
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
Console.WriteLine("Reading..");
bytesRead = clientStream.Read(message, 0, 4096);
Console.WriteLine("Received something");
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine(encoder.GetString(message, 0, bytesRead));
}
tcpClient.Close();
}
}
I simply call it in the main function like this :
Server server = new Server();
And in a separate client program I have this class
class TheClient
{
public void ConnectV2()
{
TcpClient client = new TcpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);
client.Connect(serverEndPoint);
NetworkStream clientStream = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
for (int i = 0; i < 20; i++)
{
byte[] buffer = encoder.GetBytes("Hello Server! " + i.ToString() + " ");
Console.WriteLine("Processing..");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
Console.WriteLine("Hello Server sent");
}
}
}
I call it in the main function like
TheClient tc = new TheClient();
tc.ConnectV2();
My problem is that the server program seems slower than the client, he don't react before the 13th, or more, message from the client :
[I can't post images because of reputation]
It reads the first dozen of messages in one go, and then reads the others one by one.
And if I make the server emit first, the client receive the message, but they both stop, like if both wait for the other to send something.
Can someone explain me this behavior ? How can I control and synchronize it ?
TCP is not message based. It provides a stream of bytes. It is your responsibility to separate messages. Also note, that you might receive only a part of a message in one Read call.
Here's a simple way to do that: Send the messages as individual lines. Possibly using StreamWriter. Receive the messages using StreamReader.ReadLine().
That way you can also use a more sane encoding such as Encoding.UTF8.
Besides that your code is actually fine and workable. It is extremely rare to see almost working TCP code on Stack Overflow. Most code is horribly broken. Congratulations.
It's because that your client AP is always sending data ,but your server AP cannot receive those data right away. So,those data stacked in buffer and then server AP receive all at once.
You can try:
Set fixed lengths when you send or receive data.
or
Receive and split data.
I am currently trying to write an app for android with Xamarin where I want to create and destroy sockets to the same device, and then redo that process over again. I have written both client and server code. I am having a problem doing that, since the app always crashes on the server side when it tries to read data from the client for a second time.
What I mean is that it is always successful the first time around, but the second time around, it always crashes. We figured out that the problem was on the client though cause once we started keeping the sockets open and reusing them instead of closing them and recreating a new one when needed, it worked as intended and did not crash. Here is the code we ended up using:
[SERVER]
public class BluetoothSocketListener {
private BluetoothScanner _scanner;
private BluetoothServerSocket serverSocket;
private string TAG = "Socket Listener: ";
private Thread listenThread;
public BluetoothSocketListener(BluetoothScanner scanner, UUID uuid) {
_scanner = scanner;
BluetoothServerSocket tmp = null;
try {
tmp = scanner.Adapter.ListenUsingInsecureRfcommWithServiceRecord("AGHApp", uuid);
} catch(Exception e) {
Console.WriteLine(TAG + "Listen failed, exception: " + e);
}
serverSocket = tmp;
listenThread = new Thread(new ThreadStart(StartListening));
listenThread.Start();
}
private void StartListening() {
Console.WriteLine(TAG + "Listening...");
BluetoothSocket socket = null;
while(_scanner.Running){
try {
socket = serverSocket.Accept();
}catch(Exception e) {
Console.WriteLine(TAG + "Accept failed: " + e);
break;
}
if (socket != null) {
lock (this) {
ReadData(socket.InputStream);
socket.Close();
}
}
}
serverSocket.Close();
}
private void ReadData(Stream stream) {
// Check to see if this NetworkStream is readable.
if(stream.CanRead){
byte[] streamData = new byte[1024];
StringBuilder completeMsg = new StringBuilder();
int bytesRead = 0;
// Incoming message may be larger or smaller than the buffer size.
do{
bytesRead = stream.Read(streamData, 0, 1);
completeMsg.AppendFormat("{0}", Encoding.ASCII.GetString(streamData, 0, bytesRead));
}
while(stream.IsDataAvailable());
// Print out the received message to the console.
Console.WriteLine("Message : " + completeMsg);
}
else{
Console.WriteLine("Cannot read from stream");
}
}
}
[CLIENT]
private void SendData(BluetoothDevice device, string msg){
Console.WriteLine(TAG + "Finding socket");
BluetoothSocket socket = null;
if(sockets.ContainsKey(device.Address)) {
socket = sockets[device.Address];
}
else {
socket = device.CreateInsecureRfcommSocketToServiceRecord(_uuid);
socket.Connect();
sockets.Add(socket);
}
Console.WriteLine(TAG + "Socket connected, writing to socket");
byte[] bMsg = Encoding.ASCII.GetBytes(msg);
socket.OutputStream.Write(bMsg, 0, bMsg.Length);
socket.OutputStream.Close();
}
As can be seen, I never actually close the sockets on the client side after I send the message. This is not the problem though since if this is necessary, I can easily do this in some other function.
What I would like is to create and close the socket every time I want to send a message, since I only want to send something every 15 minutes, and the device might have moved and is no longer available. It is also not necessary to keep track of the devices. Fire and forget. This is what we started with and would like to have something similar to this as well:
private void SendData(BluetoothDevice device, string msg){
BluetoothSocket socket = device.CreateInsecureRfcommSocketToServiceRecord(_uuid);
socket.Connect();
Console.WriteLine(TAG + "Socket connected, writing to socket");
byte[] bMsg = Encoding.ASCII.GetBytes(msg);
socket.OutputStream.Write(bMsg, 0, bMsg.Length);
socket.OutputStream.Close();
socket.Close();
Console.WriteLine(TAG + "Socket closed");
}
Something to notice is that the server actually closes the socket after it receives the message, why is that even working? And why can't I close the socket on the client side? Am I missing something integral here?
The exception is a Java.IO exception, where the message reads: bt socket closed, read -1
Would really appreciate some help!
I want to send a message from a C# application to the Android emulator or device over TCP. I have searched on Google and got the maximum results for Android client and C# server but not what I want to acheive.
Here is what I have tried; maybe I am going about it the wrong way but what I want is to send a message over TCP to an Android device.
Server Code to send a message:
private static int port = 4444;
private static TcpListener listener;
private static Thread thread;
private static int clientId = 0;
listener = new TcpListener(new IPAddress(new byte[] { 127, 0, 0, 1 }), port);
thread = new Thread(new ThreadStart(Listen));
thread.Start();
private static void Listen()
{
listener.Start();
MessageBox.Show("Listening on: " + port.ToString());
while (true)
{
MessageBox.Show("Waiting for connection....");
MessageBox.Show("Client No: " + clientId);
TcpClient client = listener.AcceptTcpClient();
Thread listenThread = new Thread(new ParameterizedThreadStart(ListenThread));
listenThread.Start(client);
}
}
private static void ListenThread(Object client)
{
NetworkStream netstream = ((TcpClient)client).GetStream();
MessageBox.Show("Request made");
clientId = clientId + 1;
// String message = "Hello world";
byte[] resMessage = Encoding.ASCII.GetBytes(clientId.ToString());
netstream.Write(resMessage, 0, resMessage.Length);
netstream.Close();
}
Client Code
private TextView textDisplay;
Socket socket;
private static final int TCP_SERVER_PORT = 4444;
ServerSocket ss = null;
try {
ss = new ServerSocket(TCP_SERVER_PORT);
//ss.setSoTimeout(10000);
//accept connections
Socket s = ss.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//receive a message
String incomingMsg = in.readLine() + System.getProperty("line.separator");
Log.d("TcpServer", "received: " + incomingMsg);
textDisplay.append("received: " + incomingMsg);
//send a message
String outgoingMsg = "goodbye from port " + TCP_SERVER_PORT + System.getProperty("line.separator");
out.write(outgoingMsg);
out.flush();
Log.d("TcpServer", "sent: " + outgoingMsg);
textDisplay.append("sent: " + outgoingMsg);
//SystemClock.sleep(5000);
s.close();
} catch (InterruptedIOException e) {
//if timeout occurs
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
Log.d("Error",e.toString());
}
}
}
The problem lies in your Client code.
A socket is opened between two parties, one that plays the role of the listener / server that does bind->listen->accept and a client that connect
In your code there are two problems:
Your client should connect and not accept
Both your client and your server will try to read from the socket and write afterwards. There would be no problem if your read and write operations from the socket were on different threads.In your case this will result in a deadlock.
If you want both operations to be done on the same thread , sequentially then your client and server should perform the read and write in opposite order :
Client : read -> write
Server: write-> read
I'm running a TCP server in c#. The program seems to run and hold for new clients (it stop on TcpClient client = this.tcpListener.AcceptTcpClient();) waiting for new connections. However if I check the network (using the netstat command) the server is not listening, wich means is not running. I also tryied with different ports, but I guess than port 80 should be good for testing (I also tried with other ports and none of them worked). What is wrong in my code? Maybe the OS is blocking the server?
namespace TCPServer
{
class TestClass
{
static void Main(string[] args)
{
Server TCPServer = new Server();
// Display the number of command line arguments:
System.Console.WriteLine(args.Length);
}
}
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
this.tcpListener = new TcpListener(IPAddress.Any, 80);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
System.Console.WriteLine("Server started");
}
//starts the tcp listener and accept connections
private void ListenForClients()
{
this.tcpListener.Start();
System.Console.WriteLine("Listener started");
while (true)
{
System.Console.WriteLine("Accepting Clients");
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
System.Console.WriteLine("Client connected");
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
//Read the data from the client
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client; //start the client
NetworkStream clientStream = tcpClient.GetStream(); //get the stream of data for network access
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0) //if we receive 0 bytes
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
//Reply
byte[] buffer = encoder.GetBytes("Hello Client!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
tcpClient.Close();
}
}
}
Update:
I configure the app to get a firewall exemption. Im running in windows7. I also checked with the port 3000 and nothing listening on that port. I use the netstat output to determine if its listening or not.
I have written an asynchronous server in C# and a TCP client in Java for and an Android app. The client can send messages fine to the server and they are received when they are sent. However when I send a message from the server to the client, the client only displays the message after the server is shutdown (i.e. when the socket closes).
The strange thing is that I have written a client in C# as well and that receives messages as soon as they are sent.
The C# server and client both use the asynchronous begin* and end* methods and the Java client uses a stream reader/writer.
Can anyone please suggest why the Java client is behaving in this way and how to remedy this?
Thanks.
Client Code:
public void run() {
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
socket = new Socket(serverAddr, SERVERPORT);
try {
if (out != null)
{
//send the message to the server
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
Log.e("TCP Client", "C: Sent.");
Log.e("TCP Client", "C: Done.");
}
//receive the message which the server sends back
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//in this while the client listens for the messages sent by the server
while (mRun) {
serverMessage = in.readLine();
if (serverMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(serverMessage);
serverMessage = null;
}
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
socket.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
Server Code:
public void Send(String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
socket.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), socket);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
//Retrieve the socket from the state object.
Socket clientSocket = (Socket)ar.AsyncState;
//send the data
int bytesSent = clientSocket.EndSend(ar);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
My guess is that the data you send from the server doesn't end with an EOL sequence (\n or \r\n). So the readLine() method at client-side never returns, since it can only return when it's sure the line is terminated (i.e. when an EOL sequence is received, or the connection is closed).