Android NIO Server Selectors Reading When no message is sent - java

I'm trying to use a NIO server to read/write to a client for TCP connections. I've made a successful connection, and my initial message is sent to the server and correctly processed. It says that the server is sending a message back, but I'm not receiving any input on the client side. Also, after the server sends a message back, the application crashes saying that it was trying to read a null pointer (Line 127 server code).
It's important to note that I'm new to this concept and I don't really understand selectors. I've looked at tutorials, but contradictary messages have led me to be even more confused on the issue. If anyone has any good tutorials on this topic I'd be greatly appreciative.
Here's my code.
Client Main Activity Screen
package com.example.client;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.example.client.ServerService.Connect;
public class MainActivity extends Activity {
Button button;
TextView textView;
EditText editText;
EditText editTextps;
static Handler handler;
Connect connect=null;
Object myLock=new Object();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button) findViewById(R.id.button1);
textView=(TextView) findViewById(R.id.textView1);
editText=(EditText) findViewById(R.id.editText1);
editTextps=(EditText) findViewById(R.id.editText2);
handler=new Handler(){
#Override
public void handleMessage(Message msg) { //Handle code for receiving messages
super.handleMessage(msg);//when a message is received it's input is processed here
Bundle bundle=msg.getData();
if(bundle.getInt("int") == 2){
if(bundle.getInt("valid") == 1){
Intent i = new Intent();
i.setClassName("com.example.client",
"com.example.client.ReadyScreen");
startActivity(i);
}else{
alertMessage();
editText.setText("");
editTextps.setText("");
}
}
}
};
startService(new Intent(getBaseContext(), ServerService.class));
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
String str=editText.getText().toString();
String strps=editTextps.getText().toString();
Message msg=Message.obtain();
Bundle bundle=new Bundle();
bundle.putString("name", str);
bundle.putString("password", strps);
msg.setData(bundle);
ServerService.threadHandler.sendMessage(msg);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void alertMessage() {
final android.app.AlertDialog.Builder show = new AlertDialog.Builder(this).setTitle("Error").setMessage("Wrong username/password").setNeutralButton("close", null);
show.show();
}
}
Server Service where I'm running the connection and IO
package com.example.client;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
public class ServerService extends Service {
Handler handler;
static MyHandle threadHandler;
Connect connect=null;
Object myLock=new Object();
static SocketChannel socketChannel=null;
public ByteBuffer sendBuffer=ByteBuffer.allocate(1024);
static ByteBuffer receiveBuffer=ByteBuffer.allocate(1024);
static Selector selector;
private static final String TAG = ServerService.class.getSimpleName();
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
Log.d(TAG, "Started running the service");
System.out.println(TAG + "Started running the service");
(new Thread(new ReceivingThread())).start();
(new Thread(new SendingThread())).start();
return START_STICKY;
}
#Override
public void onDestroy(){
super.onDestroy();
Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
}
class Connect {
SocketChannel socketChannel=null;
public ByteBuffer sendBuffer=ByteBuffer.allocate(1024);
ByteBuffer receiveBuffer=ByteBuffer.allocate(1024);
Selector selector;
public Connect() {
try {
socketChannel=SocketChannel.open();
SocketAddress remoteAddress=new InetSocketAddress("192.168.2.17", 20001);
socketChannel.connect(remoteAddress);
socketChannel.configureBlocking(false);
selector=Selector.open();
socketChannel.register(selector, SelectionKey.OP_READ);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class ReceivingThread implements Runnable{
#Override
public void run() {
Log.d(TAG, "Started running the receive thread");
connect=new Connect();
try {
while(true){
if(connect.selector.select()==0)
continue;
Play receivedMessage = new Play();
receivedMessage.play();
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
public class SendingThread implements Runnable{
#Override
public void run() {
Log.d(TAG, "Started running the send thread");
Looper.prepare();
threadHandler=new MyHandle(Looper.myLooper());
Looper.loop();
}
}
class MyHandle extends Handler{
public MyHandle(){
}
public MyHandle(Looper looper){
super(looper);
}
public void handleMessage(Message msg){
String str=msg.getData().getString("name");
String strps=msg.getData().getString("password");
MyMessage message=new MyMessage();
message.setb((byte)1);
message.setUsername(str);
message.setPassword(strps);
try {
connect.sendBuffer.clear();
connect.sendBuffer.put(message.Message2Byte());
connect.sendBuffer.flip();
connect.socketChannel.write(connect.sendBuffer);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
The Server Code
package mytcp;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
public class NioServer {
/**
* #param args
*/
private int port = 20001;
final makeFlagFalse timerFlag = new makeFlagFalse();
static makeFlagFalse loginLoopBoolean = new makeFlagFalse();
private static ByteBuffer sBuffer = ByteBuffer.allocate(1024);
private static ByteBuffer rBuffer = ByteBuffer.allocate(1024);
private static Map<SocketChannel, Integer> clientsMap = new HashMap<SocketChannel, Integer>();
private Selector selector = null;
private ServerSocketChannel serverSocketChannel = null;
private Object gate = new Object();
public NioServer(int port) {
this.port = port;
try {
init();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException, IOException {
final NioServer server = new NioServer(20001);
Thread accept = new Thread() {
public void run() {
server.accept();
}
};
accept.start();
while (loginLoopBoolean.flag == true)
server.loginService();
server.gamePlay(clientsMap);
}
public void init() throws IOException {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().setReuseAddress(true);
// serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(port));
System.out.println("服务器启动");
}
public void accept() {
while (true) {
try {
SocketChannel socketChannel = serverSocketChannel.accept();
System.out.println("receive the connection from "
+ socketChannel.socket().getInetAddress() + ":"
+ socketChannel.socket().getPort());
socketChannel.configureBlocking(false);
synchronized (gate) {
selector.wakeup();
socketChannel.register(selector, SelectionKey.OP_READ);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
System.out.println("Damn it");
}
}
}
public void loginService() throws InterruptedException {
synchronized (gate) {
}
try {
int n = selector.select();
if (n == 0){}
else{
Set<SelectionKey> selectionKeys = selector.selectedKeys();
for (SelectionKey key : selectionKeys) {
try {
if (key.isReadable()) {
handle_receive_login(key);
}
} catch (Exception e) {
try {
if (key != null) {
key.cancel();
key.channel().close();
}
} catch (Exception ex) {
e.printStackTrace();
}
}
}
selectionKeys.clear();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void handle_receive_login(SelectionKey key) {
SocketChannel socketChannel = null;
ServerMessage message = null;
ServerMessage sendMessage = new ServerMessage();
socketChannel = (SocketChannel) key.channel();
rBuffer.clear();
try {
int count = socketChannel.read(rBuffer);
if (count > 0) {
rBuffer.flip();
message = ServerMessage.byte2Message(rBuffer.array());
System.out.println("Receive from"+ socketChannel.socket().getInetAddress() + " : "+ message.getb());
switch(message.getb()){
case(1):
int valid = DB.idCheck(message.getUsername(),
message.getPassword());
sendMessage.setb((byte) 2);
sendMessage.setValid(valid);
sendMes sendMes = new sendMes(sendMessage, socketChannel);
sendMes.send();
break;
case(2):
break;
case (3):
if(timerFlag.flag){
if(message.getReady() == 1){
if(clientsMap.size() < 6){
clientsMap.put(socketChannel, clientsMap.size() + 1);
sendMessage.setb((byte) 3);
sendMessage.setReady(1);
sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
sendMes1.send();
}
else{
sendMessage.setb((byte) 3);
sendMessage.setReady(0);
sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
sendMes1.send();
}
Timer timer = new Timer();
System.out.println("flag is " + timerFlag.flag);
TimerTask task = new TimerTask(){
public void run(){
timerFlag.falsify();
System.out.println("flag now is " + timerFlag.flag);
}
};
timer.schedule(task, 20*1000);
}
}else{
sendMessage.setb((byte) -1); /*-1 implies that game is currently in progress*/
sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
sendMes1.send();
}
break;
case (4):
if(timerFlag.flag == true){
sendMessage.setb((byte) -2); /*send message saying "waiting for other players*/
sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
sendMes1.send();
}else{
loginLoopBoolean.falsify();
}
break;
}
}/*end of if(count=0)*/
} catch (Exception e) {
e.printStackTrace();
key.cancel();
try {
socketChannel.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public void gamePlay(Map<SocketChannel, Integer> clientsMap) throws IOException, InterruptedException{
Dealer dealer = new Dealer();
dealer.createDeck();
ServerMessage sendMessage = new ServerMessage();
if(!clientsMap.isEmpty()){
Set<SocketChannel> clientSet = clientsMap.keySet();
Iterator<SocketChannel> iterator=clientSet.iterator();
SocketChannel currentPlayer;
while(iterator.hasNext()){
currentPlayer=iterator.next();
sendMessage.setb((byte) 4);
sendMessage.setCard1(dealer.dealCard(dealer.deck));
sendMessage.setCard2(dealer.dealCard(dealer.deck));
sendMes sendMes1 = new sendMes(sendMessage, currentPlayer);
sendMes1.send();
}
//send who's turn it is
loginService();
}
}
public static class makeFlagFalse{
boolean flag;
public makeFlagFalse() {
this.flag = true;
}
public void falsify(){
flag = false;
}
public void makeTrue(){
flag = true;
}
}
public class sendMes{
ServerMessage message;
SocketChannel currentPlayer;
sendMes(ServerMessage message,SocketChannel currentPlayer){
this.message = message;
this.currentPlayer=currentPlayer;
}
public void send() throws IOException{
sBuffer.clear();
sBuffer.put(message.Message2Byte());
sBuffer.flip();
currentPlayer.write(sBuffer);
}
}
}
I'm appreciative of any kind of help.
Thank you

private Object gate = new Object();
it should be volatile

Related

i have a problem with an object programing a chat with java (PC) and android java

i have an issue with an object, im writing a chat in one side a server(pc) and the other in android, both java, with the same name but diferent packages ejem: client.message and server.message, when i try to send a message to the server i get this error on server side: "java.lang.ClassNotFoundException: package com.example.chat2cliente". I used: private static final long serialVersionUID = 9146315820377038190L; at both objects and still getting that error. At client side(Android) i added AndroidManifest.xml those lines:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
please help!
Code at Server side:
package com;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Servidor {
public static void main(String[] args) throws ClassNotFoundException, Exception{
// TODO Auto-generated method stub
MarcoServidor mimarco=new MarcoServidor();
mimarco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class MarcoServidor extends JFrame implements Runnable {
private static final long serialVersionUID = -8936247556700646004L;
public MarcoServidor() {
setBounds(1200, 300, 280, 350);
JPanel milamina=new JPanel();
milamina.setLayout(new BorderLayout());
areaTexto= new JTextArea();
milamina.add(areaTexto, BorderLayout.CENTER);
add(milamina);
setVisible(true);
Thread mihilo = new Thread(this);
mihilo.start();
}
private JTextArea areaTexto;
#Override
public void run(){
// TODO Auto-generated method stub
System.out.println("Estoy a la escucha");
try {
ServerSocket servidor = new ServerSocket(9999);
String nick, ip, mensaje;
PaqueteEnvio paquete_recibido;
while(true) {
Socket misocket = servidor.accept();
ObjectInputStream paquete_datos = new ObjectInputStream(misocket.getInputStream());
paquete_recibido = (PaqueteEnvio) paquete_datos.readObject();
System.out.println(paquete_recibido.getMensaje());
nick = paquete_recibido.getNick();
ip = paquete_recibido.getIp();
mensaje = paquete_recibido.getMensaje();
areaTexto.append(nick +": " +mensaje+ " para: "+ ip+"\n");
Socket enviaDestinatario=new Socket(ip, 9090);
ObjectOutputStream paqueteReenvio = new ObjectOutputStream(enviaDestinatario.getOutputStream());
paqueteReenvio.writeObject(paquete_recibido);
paqueteReenvio.close();
enviaDestinatario.close();
misocket.close();
}
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.getLocalizedMessage());
}
}
}
Client Side:
package com.example.chat2cliente;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.os.Bundle;
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.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
Thread Thread1 = null;
EditText etIP, etPort;
TextView tvMessages;
EditText etMessage;
Button btnSend;
String SERVER_IP;
int SERVER_PORT;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etIP = findViewById(R.id.etIP);
etPort = findViewById(R.id.etPort);
tvMessages = findViewById(R.id.tvMessages);
etMessage = findViewById(R.id.etMessage);
btnSend = findViewById(R.id.btnSend);
Button btnConnect = findViewById(R.id.btnConnect);
btnConnect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tvMessages.setText("");
SERVER_IP = etIP.getText().toString().trim();
SERVER_PORT = Integer.parseInt(etPort.getText().toString().trim());
Thread1 = new Thread(new Thread1());
Thread1.start();
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
PaqueteEnvio paqueteEnvio = new PaqueteEnvio();
public void onClick(View v) {
String message = etMessage.getText().toString().trim();
paqueteEnvio.setMensaje(message);
paqueteEnvio.setIp(etIP.getText().toString().trim());
paqueteEnvio.setNick("lomo");
if (!message.isEmpty()) {
new Thread(new Thread3(paqueteEnvio)).start();
}
}
});
}
private ObjectOutputStream output;
private BufferedReader input;
class Thread1 implements Runnable {
public void run() {
Socket socket;
try {
socket = new Socket(SERVER_IP, SERVER_PORT);
output = new ObjectOutputStream(socket.getOutputStream());
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
runOnUiThread(new Runnable() {
#Override
public void run() {
tvMessages.setText("Connected\n");
}
});
new Thread(new Thread2()).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Thread2 implements Runnable {
#Override
public void run() {
while (true) {
try {
final String message = input.readLine();
if (message != null) {
runOnUiThread(new Runnable() {
#Override
public void run() {
tvMessages.append("server: " + message + "\n");
}
});
} else {
Thread1 = new Thread(new Thread1());
Thread1.start();
return;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class Thread3 implements Runnable {
//private String message;
private PaqueteEnvio message;
Thread3(PaqueteEnvio message) {
this.message = message;
}
#Override
public void run() {
try {
output.writeObject(message);
output.flush();
runOnUiThread(new Runnable() {
#Override
public void run() {
tvMessages.append("client: " + message.getMensaje().toString().trim() + "\n");
etMessage.setText("");
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Object at Server side:
package com;
import java.io.Serializable;
public class PaqueteEnvio implements Serializable{
/**
*
*/
private static final long serialVersionUID = 9146315820377038190L;
public String getNick() {
return nick;
}
public void setNick(String nick) {
this.nick = nick;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getMensaje() {
return mensaje;
}
public void setMensaje(String mensaje) {
this.mensaje = mensaje;
}
private String nick, ip, mensaje;
}
Object at Client Side:
package com.example.chat2cliente;
import java.io.Serializable;
public class PaqueteEnvio implements Serializable{
/**
*
*/
private static final long serialVersionUID = 9146315820377038190L;
public String getNick() {
return nick;
}
public void setNick(String nick) {
this.nick = nick;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getMensaje() {
return mensaje;
}
public void setMensaje(String mensaje) {
this.mensaje = mensaje;
}
private String nick, ip, mensaje;
}
Thanks for your help.

How to connect multiple clients to one host via Wifi P2P

I'm trying to create a WiFiP2P to communicate with 2 android phones and one Raspberry Pi. I want one phone as host and the second phone + Raspberry Pi as clients.
Until know i could create a test APP to connect the 2 phones via Wifi direct (tested successful). I was following a great tutorial on Youtube Wifi P2P. Unfortunately the tutorial just show how to connect one host with one client and not multiple clients.
I was trying to follow the Android developer guide, but I have not enough experience to understand everything.
I hope you guys can help me to understand what I have to change in my code and explain me why.
The following code is the exact copy from the mentioned tutorial.
Here my MainActivity:
package com.example.wifip2p;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
Button btnOnOff, btnDiscover, btnSend;
ListView listView;
TextView read_msg_box, connectionStatus;
EditText writeMsg;
WifiManager wifiManager;
WifiP2pManager mManager;
WifiP2pManager.Channel mChannel;
BroadcastReceiver mReceiver;
IntentFilter mIntentFilter;
List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
String[] deviceNameArray;
WifiP2pDevice[] deviceArray;
static final int MESSAGE_READ=1;
ServerClass serverClass;
ClientClass clientClass;
SendReceive sendReceive;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
1);
}
initialWork();
exqListener();
}
Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
switch (msg.what){
case MESSAGE_READ:
byte[] readBuff = (byte[])msg.obj;
String tempMsg = new String(readBuff,0,msg.arg1);
read_msg_box.setText(tempMsg);
break;
}
return true;
}
});
private void exqListener() {
btnOnOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(wifiManager.isWifiEnabled()){
wifiManager.setWifiEnabled(false);
btnOnOff.setText("ON");
if(mManager!=null) {
mManager.removeGroup(mChannel, null);
}
}else{
wifiManager.setWifiEnabled(true);
btnOnOff.setText("OFF");
}
}
});
btnDiscover.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
connectionStatus.setText("Discovery Started");
}
#Override
public void onFailure(int reason) {
connectionStatus.setText("Discovery Starting Failed");
}
});
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int i, long l) {
final WifiP2pDevice device = deviceArray[i];
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(getApplicationContext(),"Connected to " + device.deviceName, Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(int reason) {
Toast.makeText(getApplicationContext(),"Not Connected",Toast.LENGTH_SHORT).show();
}
});
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String msg = writeMsg.getText().toString();
Toast.makeText(getApplicationContext(),"MSG: " + msg,Toast.LENGTH_SHORT).show();
sendReceive.write(msg.getBytes());
}
});
}
private void initialWork() {
btnOnOff= findViewById(R.id.onOff);
btnDiscover = findViewById(R.id.discover);
btnSend = findViewById(R.id.sendButton);
listView = findViewById(R.id.peerListView);
read_msg_box = findViewById(R.id.readMsg);
connectionStatus = findViewById(R.id.connectionStatus);
writeMsg = findViewById(R.id.writeMsg);
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(),null);
mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
}
WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
if(!peerList.getDeviceList().equals(peers)){
peers.clear();
peers.addAll(peerList.getDeviceList());
deviceNameArray = new String[peerList.getDeviceList().size()];
deviceArray = new WifiP2pDevice[peerList.getDeviceList().size()];
int index = 0;
for(WifiP2pDevice device : peerList.getDeviceList()){
deviceNameArray[index] = device.deviceAddress;
deviceArray[index] = device;
index++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_list_item_1,deviceNameArray);
listView.setAdapter(adapter);
}
if(peers.size()==0){
Toast.makeText(getApplicationContext(), "No Devices Found",Toast.LENGTH_SHORT).show();
}
}
};
WifiP2pManager.ConnectionInfoListener connectionInfoListener = new WifiP2pManager.ConnectionInfoListener() {
#Override
public void onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo) {
final InetAddress groupOwnerAddress = wifiP2pInfo.groupOwnerAddress;
if(wifiP2pInfo.groupFormed && wifiP2pInfo.isGroupOwner){
connectionStatus.setText("Host");
serverClass=new ServerClass();
serverClass.start();
}else if(wifiP2pInfo.groupFormed){
connectionStatus.setText("Client");
clientClass = new ClientClass(groupOwnerAddress);
clientClass.start();
}
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver,mIntentFilter);
}
#Override
protected void onPause() {
super.onPause();
registerReceiver(mReceiver,mIntentFilter);
}
#Override
protected void onDestroy() {
super.onDestroy();
try {
clientClass.socket.close();
serverClass.serverSocket.close();
serverClass.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void finalize() throws Throwable {
super.finalize();
try {
clientClass.socket.close();
serverClass.serverSocket.close();
serverClass.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public class ServerClass extends Thread{
Socket socket;
ServerSocket serverSocket;
#Override
public void run() {
// serverSocket= null;
// socket = null;
try {
Log.i("ServerSocket is called", "Called");
serverSocket = new ServerSocket(8888);
socket = serverSocket.accept();
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class SendReceive extends Thread{
private Socket socket;
private InputStream inputStream;
private OutputStream outputStream;
public SendReceive(Socket skt){
socket = skt;
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while(socket!=null){
try {
bytes = inputStream.read(buffer);
if(bytes > 0){
handler.obtainMessage(MESSAGE_READ,bytes,-1,buffer).sendToTarget();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write (byte[] bytes){
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ClientClass extends Thread{
Socket socket;
String hostAdd;
public ClientClass(InetAddress hostAddress){
hostAdd = hostAddress.getHostAddress();
// socket = null;
socket = new Socket();
}
#Override
public void run() {
try {
socket.connect(new InetSocketAddress(hostAdd,8888),500);
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Here my BroadcastReceiver Class:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pManager;
import android.nfc.Tag;
import android.util.Log;
import android.widget.Toast;
import static android.content.ContentValues.TAG;
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private MainActivity mActivity;
public WiFiDirectBroadcastReceiver(WifiP2pManager mManager, WifiP2pManager.Channel mChannel, MainActivity mActivity)
{
this.mManager = mManager;
this.mChannel = mChannel;
this.mActivity = mActivity;
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)){
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,-1);
if(state==WifiP2pManager.WIFI_P2P_STATE_ENABLED){
Toast.makeText(context,"Wifi is ON",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context,"Wifi is OFF",Toast.LENGTH_SHORT).show();
}
}else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)){
if(mManager!=null){
mManager.requestPeers(mChannel,mActivity.peerListListener);
}
Log.d(TAG, "onReceive: P2P peers changed");
}else if(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)){
if(mManager==null){
return;
}
NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if(networkInfo.isConnected()){
mManager.requestConnectionInfo(mChannel,mActivity.connectionInfoListener);
}else{
mActivity.connectionStatus.setText("Device Disconnected");
}
}else if(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)){
//do something
}
}
}

how connect multiple client to a server in Android?

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.

Trouble sending string over socket in Android

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.

android tcp/ip socket won't send data to computer

i tried to make an application that send data from android to computer (java to vb.net). The data sending is working in eclipse java project, but not in android project .
But i have a problem. no incoming data to visual basic in my computer.
VB Code :
Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Public Class Form1
Dim Listener As New TcpListener(65535)
Dim Client As New TcpClient
Dim Message As String = ""
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim ListThread As New Thread(New ThreadStart(AddressOf Listening))
ListThread.Start()
End Sub
Private Sub Listening()
Listener.Start()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Client = New TcpClient("192.168.100.3", 65535)
Dim Writer As New StreamWriter(Client.GetStream())
Writer.Write(TextBox2.Text)
Writer.Flush()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If Listener.Pending = True Then
Message = ""
Client = Listener.AcceptTcpClient()
Dim Reader As New StreamReader(Client.GetStream())
While Reader.Peek > -1
Message = Message + Convert.ToChar(Reader.Read()).ToString
End While
MsgBox(Message, MsgBoxStyle.OkOnly)
End If
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Listener.Stop()
End Sub
End Class
java code :
package com.example.androidclient2;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView serverMessage;
Thread m_objThreadClient;
Socket clientSocket;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serverMessage=(TextView)findViewById(R.id.textView1);
}
public void Start(View view)
{
m_objThreadClient=new Thread(new Runnable() {
public void run()
{
try
{
clientSocket= new Socket("192.168.100.3",65535);
ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
oos.writeObject("Hellow there");
Message serverMessage= Message.obtain();
ObjectInputStream ois =new ObjectInputStream(clientSocket.getInputStream());
String strMessage = (String)ois.readObject();
serverMessage.obj=strMessage;
mHandler.sendMessage(serverMessage);
oos.close();
ois.close();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
m_objThreadClient.start();
}
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
messageDisplay(msg.obj.toString());
}
};
public void messageDisplay(String servermessage)
{
serverMessage.setText(""+servermessage);
}
}
And Thanks For The help .
Have just created and tested this class on android today:
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
public class TcpClient {
private static final String TAG = TcpClient.class.getSimpleName();
private Socket socket;
private PrintWriter out;
private boolean connected;
public TcpClient()
{
socket = null;
out = null;
connected = false;
}
public void connect(Context context, String host, int port)
{
new ConnectTask(context).execute(host, String.valueOf(port));
}
private class ConnectTask extends AsyncTask<String, Void, Void> {
private Context context;
public ConnectTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
showToast(context, "Connecting..");
super.onPreExecute();
}
#Override
protected void onPostExecute(Void result) {
if (connected) {
showToast(context, "Connection successfull");
}
super.onPostExecute(result);
}
private String host;
private int port;
#Override
protected Void doInBackground(String... params) {
try {
String host = params[0];
int port = Integer.parseInt(params[1]);
socket = new Socket(host, port);
out = new PrintWriter(socket.getOutputStream(), true);
} catch (UnknownHostException e) {
showToast(context, "Don't know about host: " + host + ":" + port);
Log.e(TAG, e.getMessage());
} catch (IOException e) {
showToast(context, "Couldn't get I/O for the connection to: " + host + ":" + port);
Log.e(TAG, e.getMessage());
}
connected = true;
return null;
}
}
public void disconnect(Context context)
{
if ( connected )
{
try {
out.close();
socket.close();
connected = false;
} catch (IOException e) {
showToast(context, "Couldn't get I/O for the connection");
Log.e(TAG, e.getMessage());
}
}
}
/**
* Send command to a Pure Data audio engine.
*/
public void send(String command)
{
if ( connected ) out.println(command +";");
}
private void showToast(final Context context, final String message) {
new Handler(context.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
});
}
}
It might help you even though I see no obvious error in your code.
Is the device on the same WiFi network as your computer? It won't work via USB for instance.

Categories

Resources