How to Create Socket Connection in Android

How to make socket connection on Android

It looks simple but I think you have an interesting and challenging problem. If you want to keep the socket open after sending messages through it, you'll need to maintain one or more threads to use that socket because, you know, Android doesn't allow networking on main thread.

Multithread programming is seldom simple and often there is more than one way to do it. E.g. in Android you can use Handlers with Loopers from HandlerThreads, or the classic Java Thread. And also AsyncTask, but I think it doesn't fit this case.

How do you intend to manage the socket lifecycle (i.e. when is it opened or closed), and in which moments is data read/written from/into the socket? Please explain better the matter so I can suggest an implementation.

EDIT

Here's an example Activity with two buttons. One button runs an AsyncTask that creates a socket and its streams, and the other button runs another AsyncTask that writes data into the socket. It's an oversimplified solution, but it should work. Note that the code needs synchronization, for different threads access the socket.

public class MainActivity extends Activity {

private SocketContainer mSocketContainer;
private final Object mSocketContainerLock = new Object();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

// onClick attribute of one button.
public void onClickPushMe(View view) {
String serverAddress;
int serverPort;
new CreateSocketAsyncTask(serverAddress, serverPort).execute();
}

// onClick attribute of other button.
public void onClickPushMeToo(View view) {
String text;
new WriteSocketAsyncTask(text).execute();
}

// Class that contains the socket and its streams,
// so they can be passed from one thread to another.
private class SocketContainer {

private Socket mSocket;
private InputStream mSocketInputStream;
private OutputStream mSocketOutputStream;

private SocketContainer(Socket socket, InputStream socketInputStream, OutputStream socketOutputStream) {
mSocket = socket;
mSocketInputStream = socketInputStream;
mSocketOutputStream = socketOutputStream;
}

private Socket getSocket() {
return mSocket;
}

private InputStream getSocketInputStream() {
return mSocketInputStream;
}

private OutputStream getSocketOutputStream() {
return mSocketOutputStream;
}
}

// AsyncTask that creates a SocketContainer and sets in into MainActivity.
private class CreateSocketAsyncTask extends AsyncTask<Void, Void, SocketContainer> {

private final String mServerAddress;
private final int mServerPort;

private CreateSocketAsyncTask(String serverAddress, int serverPort) {
mServerAddress = serverAddress;
mServerPort = serverPort;
}

protected SocketContainer doInBackground(Void... params) {
try {
Socket socket = new Socket(mServerAddress, mServerPort);
return new SocketContainer(socket, socket.getInputStream(), socket.getOutputStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
protected void onPostExecute(SocketContainer socketContainer) {
super.onPostExecute(socketContainer);
synchronized (mSocketContainerLock) {
mSocketContainer = socketContainer;
}
}
}

private class WriteSocketAsyncTask extends AsyncTask<Void, Void, Void> {

private final String mText;

private WriteSocketAsyncTask(String text) {
mText = text;
}

@Override
protected Void doInBackground(Void... params) {
synchronized (mSocketContainerLock) {
try {
mSocketContainer.getSocketOutputStream().write(mText.getBytes(Charset.forName("UTF-8")));
mSocketContainer.getSocketOutputStream().flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return null;
}
}
}

Android socket connection using socket.io 0.9.0 version

Refer this github repository and I only can find this github repository that can work for socket 0.9 version.

It may help you.

Happy coding :)

Java Client Socket Connection in Android

In your application the NetworkOnMainThreadException is occurred. From the doc you ca see that

The exception that is thrown when an application attempts to perform a
networking operation on its main thread.

So you have to call your RunSocketClient method from another thread rather than the main thread. Use a handler or asynctask or different thread to perform this operation.

To know about good designing you can see this link

http://developer.android.com/training/articles/perf-anr.html

How to connect an android client to a server written in C?

Just use socket, both Android's Java and C have it. You can read the documentation.

Or, here's the fast way. Just create Android Socket client as https://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/ does and create server as https://www.tutorialspoint.com/unix_sockets/socket_server_example.htm does.

Here's the snippet:

client.java

package com.javacodegeeks.android.androidsocketclient;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

public class Client extends Activity {

private Socket socket;

private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.0.2.2";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

new Thread(new ClientThread()).start();
}

public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

class ClientThread implements Runnable {

@Override
public void run() {

try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

socket = new Socket(serverAddr, SERVERPORT);

} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}

}

}
}

server.c in *NIX environment.

/*
C socket server example
*/

#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write

int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];

//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");

//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );

//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");

//Listen
listen(socket_desc , 3);

//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);

//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");

//Receive a message from client
while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
write(client_sock , client_message , strlen(client_message));
}

if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}

return 0;
}

Android Studio Connect to Socket server

I managed to resolve this. I just made a thread inside a "Connection" class in Android Studio.

Inside "Connection" I have some class-level variables, which I use with the thread (The thread can't modify variables in the method the thread was created but it can read class-level variables) so the thread itself makes the connection with the socket server and saves the value taken to also a class-level variable.

In the main thread (in the same method that called the thread) I used a loop that looks at the thread status, if it has finished, reads the variable and applies it where I want.

Here the code:

public class Connection{

private String HOST = "83.xx.xx.xx";
private int PORT = 5010;

private Socket socket;

private DataOutputStream dos;
private DataInputStream dis;

boolean result;
String email;

public boolean userExists(String dev) throws InterruptedException { // true = exists, false = does not exist. dev is the email to search
this.email = dev;
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
socket = new Socket(HOST, PORT);
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream((socket.getInputStream()));
dos.writeInt(1); // 1 = Sends the option for telling the server that we want to search a user
dos.writeUTF(email); //Sends the email
result = dis.readBoolean(); // Recieve if email exists or not
socket.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Couldn't connect to server");
}
}
});
thread.start();
for (int c=0; c<25; c++){ //Wait for the thread to end
if (thread.isAlive()) {
//Thread hasn't finished yet...
Thread.sleep(100);
} else if (c == 24) {
//This would be a timeout
result = false;
} else {
//Thread has finished
break;
}
}
return result; // true in case server found the email, false in case it doesn't or in case of a timeout
}

I think another possibility could be making the thread just do the connection (and another one for closing it) and saving the socket as class-level variable, so you can send and receive from the main thread, I didn't try it tho.

How can I connect two Android device by socket without server

Java provides ServerSocket and Socket to communicate b/w devices. One of the device you can make as server and other device you can make as client and communicate b/w 'em without introducing server hosted on some machine.

The Other and better option is Using Wi-Fi Peer-to-Peer. WifiP2pManager help you to achieve your purpose.Here is an example.



Related Topics



Leave a reply



Submit