I want to create a chatroom that in it 3 (or more device ) connect to a server with Tcp protocol on hotspot and server and clients cant talk to each other
this is my code that in
when app start it try to connected to server (if existed) if it don't find server then it run server socket an wait for client but only one client can connect to server and send and receive message
i know that i have to use multi-thread but i can't handle this please help me:(
package com.app.wifi_chat;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import com.uncocoder.app.wifi_chat.R;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class WifiChatActivity extends Activity {
private Handler handler = new Handler();
private TextView text;
private EditText input;
private Button btnSend;
private Socket socket;
private DataOutputStream outputStream;
private BufferedReader inputStream;
//try to connect to server if find it return true
private boolean searchNetwork() {
log("Connecting...");
String range = "192.168.1.";
for (int i = 1; i <= 255; i++) {
String ip = range + i;
try {
//log("Try IP: " + ip);
socket = new Socket();
socket.connect(new InetSocketAddress(ip, 9000), 10);
log("Connected!");
return true;
}
catch (Exception e) {}
}
return false;
}
//run server and wait for new client
private void runChatServer() {
try {
log("Waiting for client...");
ServerSocket serverSocket = new ServerSocket(9000);
socket = serverSocket.accept();
log("A new client Connected!");
}
catch (IOException e) {}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.text);
input = (EditText) findViewById(R.id.input);
btnSend = (Button) findViewById(R.id.btnSend);
//server
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
//first time check for connect to server if not to find it then run server and wait for client
if ( !searchNetwork()) {
runChatServer();
}
try {
outputStream = new DataOutputStream(socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (IOException e1) {
log("Error: Connection is not stable, exit");
shutdown();
}
//listen to client for get messeage
while (true) {
try {
String message = inputStream.readLine();
if (message != null) {
log(message);
}
}
catch (IOException e) {}
}
}
});
//send message to client or server
btnSend.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (outputStream == null) {
return;
}
try {
String message = input.getText().toString() + "\n";
outputStream.write(message.getBytes());
}
catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
}
//log messeage form client or server
private void log(final String message) {
long timestamp = System.currentTimeMillis();
final long time = timestamp % 1000000;
handler.post(new Runnable() {
#Override
public void run() {
text.setText(text.getText() + "\n #" + time + ": " + message);
}
});
}
//when app is kill close socket
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
shutdown();
return true;
}
return super.onKeyDown(keyCode, event);
}
private void shutdown() {
try {
if (socket != null) {
socket.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
System.exit(0);
}
}
Your code is a total mess.
Commonly you need to make something like this
class ClientClass implements Runnable //For managing clients
{
Socket socket;
public ClientClass(Socket s)
{
socket = s;
}
void run()
{
//Get InputStreams
//Manage client
}
}
ServerClass
while(true)
{
new Thread(new ClientClass(server.accept()));//Maybe you want to store it for future comunication
}
Hope this helps.
Related
I have a tested server on ESP8266 with loopback and a tcp client app that doesn't send messages. I also tested it on a server that tells you if there is somebody connected and it says that it connects.
The "chat" textView shows the message when I click send.
For example: Client: message, but it doesn't send it to the server for it to loop it back.
What should I change for it so send and receive messages?
Client
package com.example.tinemasilo.researchgate_sockettut;
import android.app.Activity;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
public class MainActivity extends Activity
{
static EditText serverIp,smessage;
static TextView chat;
static Button connectPhones,disconnectPhones,sent;
static String serverIpAddress = "",msg = "",str;
Handler handler = new Handler();
//static InetAddress serverAddr;
static Socket socket;
static DataOutputStream os;
//static DataInputStream in;
static BufferedReader in;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chat = (TextView) findViewById(R.id.chat);
serverIp = (EditText) findViewById(R.id.server_ip);
smessage = (EditText) findViewById(R.id.smessage);
sent = (Button) findViewById(R.id.sent_button);
connectPhones = (Button) findViewById(R.id.connectPhones);
disconnectPhones = (Button) findViewById(R.id.disconnectPhones);
connectPhones.setEnabled(true);
connectPhones.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
connectPhones.setEnabled(false);
disconnectPhones.setEnabled(true);
serverIpAddress = serverIp.getText().toString();
//try
//{
// InetAddress.getByName(serverIpAddress);
// serverAddr.getByName(serverIpAddress);
// socket = new Socket(serverAddr, 10000);
//}
// catch (IOException e)
//{
//}
if (!serverIpAddress.equals(""))
{
Thread clientThread = new Thread(new ClientThread());
clientThread.start();
}
}
});
sent.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Thread sentThread = new Thread(new sentMessage());
sentThread.start();
}
});
disconnectPhones.setEnabled(false);
disconnectPhones.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
connectPhones.setEnabled(true);
disconnectPhones.setEnabled(false);
try
{
socket.close();
}
catch (IOException e)
{
}
}
});
}
public class ClientThread implements Runnable
{
public void run()
{
try
{
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
//serverAddr.getByName(serverIpAddress);
socket = new Socket(serverAddr, 502);
while(true)
{
//InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
//serverAddr.getByName(serverIpAddress);
//socket = new Socket(serverAddr, 10000);
//in = new DataInputStream(socket.getInputStream());
in = new BufferedReader( new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = in.readLine()) != null)
{
msg = msg + "Server : " + line + "\n";
handler.post(new Runnable()
{
#Override
public void run()
{
chat.setText(msg);
}
});
}
in.close();
Thread.sleep(100);
}
}
catch (Exception e)
{
}
}
}
class sentMessage implements Runnable
{
#Override
public void run()
{
try
{
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
//serverAddr.getByName(serverIpAddress);
socket = new Socket(serverAddr, 502);
os = new DataOutputStream(socket.getOutputStream());
str = smessage.getText().toString();
str = str + "\n";
msg = msg + "Client : " + str;
handler.post(new Runnable()
{
#Override
public void run()
{
chat.setText(msg);
}
});
os.writeBytes(str);
os.flush();
os.close();
}
catch(IOException e)
{
}
}
}
}
You are trying to create a new Socket connection on same port in sentThread. First connection is created in ClientThread class and when you are pressing sent button you are creating another Socket connection on same port 502. I think that's is the main problem.
Try to use existing Socket connection in sentThread class.
class sentMessage implements Runnable
{
#Override
public void run()
{
try
{
//InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
//serverAddr.getByName(serverIpAddress);
// socket = new Socket(serverAddr, 502);
// os = new DataOutputStream(socket.getOutputStream());
str = smessage.getText().toString();
str = str + "\n";
msg = msg + "Client : " + str;
handler.post(new Runnable()
{
#Override
public void run()
{
chat.setText(msg);
}
});
os.writeBytes(str);
os.flush();
//os.close();
}
catch(IOException e)
{
}
}
}
Edit:
You you want to send multiple message then don't close DataOutputStream. Remove os.close(); and os = new DataOutputStream(socket.getOutputStream()); line from sentMessage class.
Initialize your os when you are connecting first time. Then every time you want to send message use that os instance.
In ClientThread class initialize os after connection created
socket = new Socket(serverAddr, 502);
os = new DataOutputStream(socket.getOutputStream());
I'm creating an simple app, in which I want to send message over local wifi connection using TCP. So I'm creating hotspot on one device and connect it from other device.
Now, on hosting device, I'm running following server application and on connecting device I'm running client application.
But nothing happens when I press send button on client device. My code for both server and client is as following:
Code for server:
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
import android.os.Handler;
import android.widget.TextView;
public class MainActivity extends Activity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
public static final int SERVERPORT = 6000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text2);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} 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()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
}
Code for client:
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends Activity {
private Socket socket;
private String TAG="XXX";
private static final int SERVERPORT = 5000;
private String SERVER_IP ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
SERVER_IP = getWifiApIpAddress();
}
public String getWifiApIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en
.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
if (intf.getName().contains("wlan")||intf.getName().contains("ap")) {
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr
.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()
&& (inetAddress.getAddress().length == 4)) {
Log.d(TAG, inetAddress.getHostAddress());
return inetAddress.getHostAddress();
}
}
}
}
} catch (SocketException ex) {
Log.e(TAG, ex.toString());
}
return null;
}
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);
// out.flush();
} 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();
}
}
}
}
I'm following this tutorial. As explained there, It is working fine in android emulators. But doesn't work on actual devices.
So I thought the IP address should be given different on different hotspots. So I've written a method in client code to get server hotspot's IP address and than connect to it. But still nothing happens on pressing send button.
So, What am I missing here? Is my method correct? Is there any mistakes in port numbers?
In the tutorial, author is doing something called port forwarding. What about port forwarding for actual devices?
I've searched everywhere for this on Internet but can't find any exact solution or any tutorial explaining this type of application. Please help me!
EDIT:
when I run this in real devices, It is giving NllPointerException in clients code, on following line:
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
You don't need to forward anything on device, just make sure your device is on the same network & use the port you have hard-coded or defined in the settings.
We forward port in emulator because its running on your host machine & we are telling the host to forward traffic coming on that specific port to emulator, since in an actual device you don't need to do that so you just to have to make sure your device is on the same network & correct port is being called.
Trying to do android socket programming based on this tutorial
http://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/
I have my firewall turned off and anti virus disabled. If I make my server address to 127.0.0.1 I get the error in the title. If I make it my local IP address,it just sits at socket going to be created.I have tried it without and with port forwarding and setting it to the same port.
Client
package com.bennatpjose.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.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
private Socket socket;
private TextView text;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.52.7.179";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.textView1);
new Thread(new ClientThread()).start();
text.setText(text.getText().toString()+"Client Thread should be fired");
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
text.setText(text.getText().toString()+"\n"+"Click Event "+str);
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
text.setText(text.getText().toString()+"\n"+"Next is out.println("+str+")");
out.println(str);
text.setText(text.getText().toString()+"\n"+"out.println("+str+")");
} catch (UnknownHostException e) {
text.setText(text.getText().toString()+"\nPrint Writer UnknownHostException "+e.toString());
} catch (IOException e) {
text.setText(text.getText().toString()+"\nPrint Writer IOException "+e.toString());
} catch (Exception e) {
text.setText(text.getText().toString()+"\nPrint Writer Exception "+e.toString());
}
}
class ClientThread implements Runnable {
#Override
public void run() {
text.setText(text.getText().toString()+"\nInside client thread run method ");
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
//If I set address to my local ip it just sits here and doesn't show socket created.
text.setText(text.getText().toString()+"\n"+serverAddr +" Socket going to be Created");
socket = new Socket(serverAddr, SERVERPORT);
text.setText(text.getText().toString()+"\n"+socket.toString() +"Socket Created");
} catch (UnknownHostException e1) {
text.setText(text.getText().toString()+"\nClient Thread UnknownHostException "+e1.toString());
} catch (IOException e1) {
text.setText(text.getText().toString()+"\nClient Thread IOException "+e1.toString());
}catch (Exception e1) {
text.setText(text.getText().toString()+"\nClient Thread Exception "+e1.toString());
}
}
}
}
Server
package com.bennatpjose.androidsocketserver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
public class MainActivity extends Activity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
public static final int SERVERPORT = 6000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.text2);
text.setText(text.getText().toString()+"onCreate method started");
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
text.setText(text.getText().toString()+"\n"+"serverThread started");
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
text.setText("!!Socket Stopped!!");
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
text.setText(text.getText().toString()+socket+"\n");
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} 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()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
}
So I figured it out. One of the mistakes I did was replacing the SERVER_IP with my local ip where as I should have left it at 10.0.2.2 since its a special loopback address android emulators.
10.0.2.2 Special alias to your host loopback interface (i.e., 127.0.0.1 on your development machine)
You also have to run the server first,set the port redirection and then run the client.
Look up Emulator networking section at http://developer.android.com/tools/devices/emulator.html
So I am using sockets in Android to establish a connection and then send strings from an EditText field using a send_message button in the UI.
I can establish the connection, however, when I try and send a message using sendMessage, both the Client and Server Threads go to the catch part of the statement. In the code refer to:
On the server thread: "Oops. Connection interrupted. Please reconnect your phones."
On the client thread: "except"
I saw in other StackOverflow threads that it may have to do with the PrintWriter out variable and it's scope?
Would love your help and feedback
package com.project.jaja.fleetcommander;
import com.project.jaja.fleetcommander.util.SystemUiHider;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;
public class P2PActivity extends Activity {
//Omitting non-relevant code to with fullscreen
private TextView serverStatus;
// Client IP
public String CLIENTIP;
// SERVER IP
public String SERVERIP = "10.0.2.15";
// DESIGNATE A PORT
public static final int SERVERPORT = 5554;
private Handler handler = new Handler();
private ServerSocket serverSocket = null;
private EditText serverIpField;
private boolean connected = false;
private boolean hosting = false;
public Button sendMessage;
public PrintWriter out = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_p2p);
serverIpField = (EditText) findViewById(R.id.server_ip);
serverStatus = (TextView) findViewById(R.id.server_status);
sendMessage = (Button) findViewById(R.id.send_button);
//Omitting non-relevant code to do with fullscreen
}
//Omitting non-relevant code to do with fullscreen
public void clickServer(View view) {
SERVERIP = getLocalIpAddress();
Thread fst = new Thread(new ServerThread());
fst.start();
hosting = true;
Button serverButton = (Button) findViewById(R.id.server_button);
serverButton.setEnabled(false);
}
public void clickClient(View view) {
if (!connected) {
SERVERIP = serverIpField.getText().toString();
CLIENTIP = getLocalIpAddress();
if (!SERVERIP.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
public class ServerThread implements Runnable {
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// LISTEN FOR INCOMING CLIENTS
Socket client = serverSocket.accept();
CLIENTIP = client.getInetAddress().getHostAddress();
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Connected.");
}
});
try {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line = null;
out = new PrintWriter(client.getOutputStream(), true);
sendMessage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
EditText message = (EditText) findViewById(R.id.message_field);
out.println(message.getText().toString());
message.setText("");
}
});
connected = true;
while (connected) {
line = in.readLine();
if (line.equals("GAME END")) {
serverSocket.close();
} else {
serverStatus.setText(line);
}
}
break;
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
// GETS THE IP ADDRESS OF YOUR PHONE'S NETWORK
public static String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException ex) {
ex.printStackTrace();
}
return null;
}
#Override
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
try {
Socket socket = new Socket(serverAddr, SERVERPORT);
connected = true;
while (connected) {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String input = in.readLine();
out = new PrintWriter(socket.getOutputStream(), true);
sendMessage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
EditText message = (EditText) findViewById(R.id.message_field);
out.println(message.getText().toString());
message.setText("");
}
});
if (input.equals("GAME END")) {
connected = false;
} else {
serverStatus.setText(input);
}
}
socket.close();
serverStatus.setText("socket closed");
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
serverStatus.setText("except");
Log.e("ClientActivity", "S: Error", e);
}
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
}
}
}
}
Essentially, the code aims not to distinguish too much between the client and server.
I am trying to write an app on android where, there is a multithreaded server running on a computer and in the app on the phone there is a button, once the user clicks that button a socket is opened between the server and the client. My problem is that once the user clicks that button I get a lot of runtime errors on my log cat. One of them is SocketException socket failed (Permission denied)
Here is the code for the activity that has the button that opens the socket with the server
package guc.edu.eg;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class Activity1 extends Activity {
Button start;
Button help;
Button credentials;
Socket socket;
//public DataInputStream in=null;
public PrintStream out=null;
InetAddress IP;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
//try {
//IP = InetAddress.getLocalHost();
//} catch (UnknownHostException e) {
// //TODO Auto-generated catch block
//e.printStackTrace();
//}
start = (Button) findViewById(R.id.start);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
socket= new Socket("127.0.0.1",4444);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//try {
//out = new PrintStream(socket.getOutputStream());
//out.println ("The socket is open at the phone!!");
//} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
//}
//try {
// in = new
//DataInputStream(socket.getInputStream());
// } catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
//}
Intent intent = new Intent(Activity1.this,Activity2.class);
startActivity(intent);
}
});
help = (Button) findViewById(R.id.help);
help.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Activity1.this,Activity3.class);
startActivity(intent);
finish();
}
});
credentials = (Button) findViewById(R.id.credentials);
credentials.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Activity1.this,Activity4.class);
startActivity(intent);
finish();
}
});
}
}
Here is the code for the Server class, that is actually placed in a different project other than the one that has the app code.
import java.io.*;
import java.net.*;
import java.util.LinkedList;
// Java extension packages
public class Server implements Runnable {
ServerSocket serverSocket;
Socket clientSocket;
int portNo;
LinkedList<ServerThread> allClients = new LinkedList<ServerThread>();
public Server(int port) {
portNo = port;
}
public void run() {
try {
serverSocket = new ServerSocket(portNo);
while (true) {
clientSocket = serverSocket.accept();
ServerThread x = new ServerThread(clientSocket, this);
allClients.add(x);
x.start();
}
} catch (EOFException eofException) {
System.out.println("Client terminated connection");
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
public void sendMessageToClient(String message) {
String[] x = message.split(",");
//for (int i = 0; i < allClients.size(); i++) {
//if (allClients.get(i).clientName.equals(x[2])) {
//allClients.get(i).sendMessage(x[1] + ": " + x[0]);
//return;
//}
//}
// if you didn't return then you couldn't reach your destination in your local server
// send the message to the network server to search for it
}
public String getLocalClientsNames() {
String names = "";
for (int i = 0; i < allClients.size(); i++) {
names += allClients.get(i).clientName + ",";
}
return names;
}
public void sendClientNamesToAll() {
//net.sendAllClientNames();
}
public static void main(String [] args) {
Server server = new Server(4444);
new Thread(server).start();
}
}
Here is the ServerThread class placed at the same package with the Server class
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class ServerThread extends Thread {
private Socket clientSocket;
private Server server;
String clientName;
private ObjectOutputStream output;
private ObjectInputStream input;
public ServerThread(Socket client, Server s) {
this.clientSocket = client;
this.server = s;
}
#Override
public void run() {
try {
output = new ObjectOutputStream(clientSocket.getOutputStream());
output.flush();
input = new ObjectInputStream(clientSocket.getInputStream());
processConnection();
closeConnection();
} catch (IOException e) {
System.out.println("in or out failed");
}
}
private void processConnection() throws IOException {
String message = "!!";
System.out.println("mada5alsh el while");
while (!message.equalsIgnoreCase("Client>> end")) {
try {
System.out.println("da5al el while");
message = (String) input.readObject();
System.out.print(message);
if (message.equalsIgnoreCase("Name")) {
clientName = (String) input.readObject();
server.sendClientNamesToAll();
} else {
server.sendMessageToClient(message);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public void closeConnection() throws IOException {
output.close();
input.close();
clientSocket.close();
}
public void sendMessage(String message) {
try {
output.writeObject(message);
output.flush();
} catch (IOException ioException) {
//do
}
}
}
I think it might be something that has to do with the manifest file so I added this line of code to it
`<uses-permission android:name="android.permission.INTERNET"></uses-permission>`
You create your client socket in the main thread which is not permitted.
Use a separate thread or use AsyncTask.
Adding <uses-permission android:name="android.permission.INTERNET"></uses-permission> to you AndroidManifest.xml should do the trick.