How to create and maintain a persistent socket connection in Android WiFiDirect? - java

I'm using WiFiDirect to connect two phones and transfer images between them. I'm able to connect the devices and transfer 1 image from client to server. I'm failing when I try to transfer more than 1 image.
I use onConnectionInfoAvailable method to launch my server and client threads.
#Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
Log.i(TAG, "GO address " + info.groupOwnerAddress.getHostAddress() + " isGroupOwner " + info.isGroupOwner);
this.info = info;
if (info.groupFormed && info.isGroupOwner) {
ServerRunnable serverRunnable = new ServerRunnable(imageToBeSet);
Thread serverThread = new Thread(serverRunnable);
serverThread.start();
} else {
//Start client thread and transfer image.
}
ServerRunnable :
public class ServerRunnable implements Runnable {
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
Socket clientSocket = serverSocket.accept();
while (connected) {
try {
InputStream inputStream = clientSocket.getInputStream();
final byte[] result = streamToByteArray(inputStream);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);
clientImage.setImageBitmap(bitmap);
}
});
} catch (Exception e) {
//Handle exception
}
}
} catch (Exception e) {
//Handle exception
}
}
}
ClientRunnable :
public class ClientRunnable implements Runnable {
public void run() {
try {
Log.d("ClientActivity", "C: Connecting...");
Thread.sleep(2000l);
socket.bind(null);
socket.connect(new InetSocketAddress(host, PORT), 5000);
while (connected) {
if(outputStream == null) {
try {
outputStream = socket.getOutputStream();
} catch (Exception e) {
// Handle exception
}
}
}
} catch (Exception e) {
// Handle exception
}
}
public void write(byte[] bytes) {
try {
outputStream.write(bytes, 0, bytes.length);
} catch (IOException e) {
e.printStackTrace();
}
}
}
The above write method does not work. The OutputStream is connected to the server socket when I debug I see the info about me server (ip address and post number). Not sure why the write is not being read by my server. The socket shows as connected too.
The first transfer works fine. I have a layout with Previous and Next buttons. When the button is pressed, I want to read the image byte array and transfer that. I'm unable to do this part.
If anyone knows how I can create and maintain a persistent socket connection, or any other way to transfer multiple images from client to server using WiFiDirect please let me know. I based this off of the WiFiDirectDemo in Android SDK samples.
Thanks,
Akash
P.S.: I've also looked at the WiFiP2PDemo which uses a WifiP2pDnsSdService. I'm currently trying to understand how they are keeping the sockets open for continuous chat.

Related

Android keep socket connection open on thread

thank you for your help.
I'm trying to stream sensor data from my android device to a server via TCP socket. I'm fairly new to Android and threads are a tough concept for me to grasp.
I have two methods, connectToServer() and sendDataToServer(). connectToServer() is called once at startup and sendDataToSever() is called over and over again at about 100 HZ. I would like to open the socket at connectToServer() and leave it open always, so that sendDataToServer() can send data on that socket repeatedly.
public static void connectToServer(){
sendThread = new Thread(new Runnable() {
public void run() {
mySocket = null;
os = null;
try {
mySocket = new Socket(PC_IP, PORT);
os = new DataOutputStream(mySocket.getOutputStream());
} catch (UnknownHostException exception) {
Log.d("sunnyDay", exception.getMessage());
} catch (IOException exception) {
Log.d("sunnyDay", exception.getMessage());
}
}
});
sendThread.start();
}
public static void sendDataToServer(byte[] data) {
String dataString = Arrays.toString(data);
// send this String to the server
sendThread = new Thread(new Runnable() {
public void run() {
if (mySocket != null && os != null) {
try {
os.writeBytes(dataString + "\n");
} catch (IOException exception) {
Log.d("sunnyDay", exception.getMessage());
}
}
}
});
sendThread.start();
}
The only way I've been able to repeatedly send data is by closing and reopening the socket every time in the same thread call, although I feel like this is not the solution.
I tried to have them both on the same thread so that the socket connection is still there, I'm assuming this is where I'm missing something about threads.
Any input is greatly appreciated.
Thanks!
os.flush() after os.writeBytes(dataString + "\n");

TCP Android Server and C# Client

I am trying to create an Android Server and Client on C# base on TCP Socket. I want them both to send and received a string(Data) so I can make a command base on the given string(Data). For the meantime, the Server can listen to incoming clients and the Clients can connect to Server. But I have two problem and i can't solve it.
PROBLEMS:
1. When i try to send the data to Server, the Server was unable to Read it.
2. When the Client is Disconnected, the Server is giving me a loop of Null.
I already try to Search about communicating C# and Android using TCP but i didn't found anything like what i need.
The following code is for Android Server.
I am having a loop of Null in class CommunicationThread when the client is Disconnected. I think it's because I am using a while for reading the Data from client, but since it become disconnected then it is resulting a null.
public class MainActivity extends AppCompatActivity {
TextView tx1, tx_waiting;
private ServerSocket serverSocket;
Handler updateConversationHandler, dg;
Thread serverThread = null;
public static final int SERVERPORT = 6000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tx1 = (TextView)findViewById(R.id.textView1);
tx_waiting = (TextView)findViewById(R.id.tx_waiting);
//Start the Server
try{
updateConversationHandler = new Handler();
dg = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
tx_waiting.setVisibility(View.VISIBLE);
Log.d("Server Starting","Server Already Started.");
}catch (Exception e){
e.printStackTrace();
}
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
Log.d("Server Stop","Successfully Stopped the Server Without any Error.");
} catch (IOException e) {
Log.e("Server Failed to Stop",e.toString());
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
Log.d("Server Thread","Server Thread Already Started.");
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
Log.d("Server Socket","New Client is Connected");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
Log.d("Input Stream","Input Stream Received!.");
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
Log.d("Update Convers.","Conversation was Updating...");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
Log.d("Client Data",msg.toString());
}
}
}
The following code is for C# Client to Connect and Send the Data.
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
NetworkStream serverStream = default(NetworkStream);
Task f = Task.Factory.StartNew(() => {
//Connect the Client into Server
try {
clientSocket.Connect(tb_ip.Text, int.Parse(tb_port.Text));
}
catch (Exception ezz) {
MessageBox.Show("Server Not Found.");
}
//Assuming that the CLient is Connected then Send a Sample Data
try {
serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes("This is Sample Data");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}
catch (Exception er) {
Console.WriteLine(er.ToString());
}
});
I have no method yet for Sending the Data from Server to Client since I am just starting to make this thing works, But if you have anything that can help me about this then i will really appreciate it. Thanks.

Java chat application only picking up some sent messages

I'm writing an all-in-one java chat program which will either act as a client or a server. I'm currently having this problem where, after the connection is established, the program only successfully recieves (or sends?) some of the messages. I've used a loop to spam through a load of junk and I've seen that the other end will only pick up some of the messages. I've never got a message to send manually.
Here is the code:
public class ConnectionThread implements Runnable {
private Connection c = Connection.getInstance();
private ChatInterface chatInterface;
private static ConnectionThread serverThread;
private ServerSocket serverSocket;
private Socket socket;
private ObjectInputStream dataIn;
private ObjectOutputStream dataOut;
public ConnectionThread() {}
public static synchronized ConnectionThread getInstance() {
if (serverThread == null) {
serverThread = new ConnectionThread();
}
return serverThread;
}
public void run() {
// If the programs role is server, set up the server
if (c.getRole() == ConnectionRole.SERVER) {
try {
setupServer();
waitForConnection();
setupStreams();
} catch (IOException e) {
e.printStackTrace();
}
do {
try {
chatInterface.addToChatHistory(dataIn.readUTF());
} catch (IOException e) {
e.printStackTrace();
}
} while (c.getRole() == ConnectionRole.SERVER);
}
// If the programs role is client, set up a connection to the server
if (c.getRole() == ConnectionRole.CLIENT) {
try {
setupClient();
setupStreams();
} catch (IOException e) {
e.printStackTrace();
}
do {
try {
chatInterface.addToChatHistory(dataIn.readUTF());
} catch (IOException e) {
e.printStackTrace();
}
} while (c.getRole() == ConnectionRole.CLIENT);
}
}
private void setupClient() throws IOException {
System.out.println("ATTEMPTING TO CONNECT...");
socket = new Socket("127.0.0.1", 8080);
System.out.println("CONNECTED!");
}
private void setupServer() throws IOException {
System.out.println("SETTING UP SERVER..");
serverSocket = new ServerSocket(8080, 1);
System.out.println("SERVER SETUP");
}
private void waitForConnection() throws IOException {
System.out.println("WAITING FOR A CONNECTION...");
socket = serverSocket.accept();
System.out.println("CONNECTION RECIEVED");
}
private void setupStreams() throws IOException {
System.out.println("SETTING UP STREAMS...");
dataOut = new ObjectOutputStream(socket.getOutputStream());
dataIn = new ObjectInputStream(socket.getInputStream());
chatInterface = ChatInterface.getInstance();
System.out.println("STREAMS SETUP");
}
public void sendMessage(String message) throws IOException {
System.out.println("SENDING MESSAGE...");
dataOut.writeUTF(message);
chatInterface.addToChatHistory(message);
System.out.println("MESSAGE SENT!");
}
}
Can anyone tell me why not all messages are being sent/picked up properly? I've been playing with it for quite a while now and I can't figure out why.
I found out after following EJP's recommendation to switch to DataInput/OutputStreams which worked straight away. Although I did need to be using ObjectInput/OutputStreams so I switched back. I found that I got the same issue again, until I switched to write/readObject instead of write/readUTF. If I cast the readObject to (String) it would then manage to receive every message.
So if anyone is having the same problem with ObjectInput/OutputStreams using write/readUTF try using write/readObject instead.

Android Socket Programming, continuous server-client communication (on Button-hit)

So, i have a Android-App(Client) and a Java-program(Server), with a One-time socket communication, whenever the android app connects to my server in a special activity (working fine).
Because my server is embedded in a bigger program (with Swing-components, where the server takes its informations from), i have this (reduced) code here:
//somewhere in my Swing-Application
Server myServer = new Server();
myServer.start();
//...
public class Server extends Thread {
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(8090);
try {
while (true) {
System.out.println("Server is waiting for connections...");
socket = serverSocket.accept();
startHandler(socket);
}
} finally {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void startHandler(final Socket socket) throws IOException {
System.out.println("Client connected to Server");
Thread thread = new Thread() {
#Override
public void run() {
try {
writer = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
//doing something usefull, i am sending a JSON-String, which i´ll parse in my app.
writer.write(someStringContainingJSONString);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
closeSocket();
}
}
private void closeSocket() {
try {
socket.close();
} catch (IOException e) {
}
}
};
thread.start();
}
In my Android-App i have:
public void onCreate(Bundle savedInstanceState) {
viewJSON = new Runnable() {
#Override
public void run() {
getJSON();
}
};
Thread thread = new Thread(null, viewJSON, "MagentoBackground");
thread.start();
myProgressDialog = ProgressDialog.show(myActivity.this, "Please wait...", "Retrieving data ...", true);
}
private void getJSON() {
try {
socket = new Socket(serverIPAddress, SERVER_PORT);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
String help = reader.readLine();
// parse this String according to JSON, is working fine!
}
// catch and so on...
Now, i want the app, to recieve data, whenever i hit a button "send data" from my Swing-Application, to have the newest data available.
On the other hand, i want the server to recieve data (also a JSON-String) when i make changes in my Android app. The String should also be send when i hit a specific button.
How can i do that? The problem is the threading issue(otherwise my swing application wouldn´t work) combined with networking. If i don´t close the socket, i cannot continue with my program properly (or at least, it seems so with my code right now)
Can you help me out here?
Thank you very much in advance for your help and thoughts.
Best, Andrea

1 server 2 clients java

i want to make a game with 2 players .i will use udp server and 2 clients and i dont
know how to connect 2 clients to 1 server at the same time and how they will communicate.
I will use only java.At last how the mouse click will syncronize with server
public void mousePressed(MouseEvent event) {
}
public void mouseReleased(MouseEvent event) {
}
public void mouseEntered(MouseEvent event) {
}
public void mouseExited(MouseEvent event) {
}
the server
public class Provider {
public ServerSocket providerSocket;
Socket connection = null;
ObjectOutputStream out;
ObjectInputStream in;
String message;
String[] torino={"null","null"};
Provider() {}
void run()
{
try {
//1. creating a server socket (8080=port , 2 =number of connections)
providerSocket = new ServerSocket(8080, 2 );
//2. Wait for connection
System.out.println("Waiting for connection");
connection = providerSocket.accept();
System.out.println("Connection received from " + connection.getInetAddress().getHostName());
//3. get Input and Output streams
out = new ObjectOutputStream(connection.getOutputStream());
// flush= clean the object out
out.flush();
in = new ObjectInputStream(connection.getInputStream());
sendMessage("Connection successful");
//4. The two parts communicate via the input and output streams
try {
//take the message from client
message = (String)in.readObject();
if (torino[0]=="null")
torino[0]=message;
} else if (torino[1]=="null") {
torino[1]=message;
}
}
catch(ClassNotFoundException classnot) {
System.err.println("Data received in unknown format");
}
} catch(IOException ioException) {
ioException.printStackTrace();
}
finally {
//4: Closing connection
try {
in.close();
out.close();
providerSocket.close();
} catch(IOException ioException) {
ioException.printStackTrace();
}
}
}
//method to send messages from server to clients
void sendMessage(String msg)
{
try {
out.writeObject(msg);
out.flush();
System.out.println("server>" + msg);
}
catch(IOException ioException) {
ioException.printStackTrace();
}
}
//main method
public static void main(String args[])
{
Provider server = new Provider();
while(true) {
server.run();
}
}
So now you can see in your code that you have a point where the server socket is waiting for a connection. That is the accept() method. At that point, you need to create a new Thread for handling the connection and let the main thread continue waiting for another connection. You may want to keep track of the number of connections made in a variable, say numConnections.
while(numConnections < 2){
connection = providerSocket.accept();
Thread t = new Thread(new ConnectionHandler(connection));
t.start();
numConnections++;
}
Now you ConnectionHandler class will do the work of the connection:
class ConnectionHandler implements Runnable{
Socket connection;
public ConnectionHandler(Socket connection){
this.connection = connection;
}
public void run(){
//here you do all the code associated with handling the connection
//such as your Object Streams and so on.
}
}
A quick Google search turns up many tutorials and examples of doing this such as this one. There are also some YouTude videos. You may want to start with one of those.

Categories

Resources