I have desktop and android applications, which connected by bluetooth(in desktop side I use Bluecove 2.1.1 library). Desktop application create bluetooth service then android application connects to it. I want to add logout functionality from both desktop and android sides. For example in desktop app user click disconnect, both desktop and android apps reset their connections and should be able to connect again. Here is bluetoothService code for desktop side:
public class BluetoothService
{
private static final String serviceName = "btspp://localhost:"
// + new UUID("0000110100001000800000805F9B34F7", false).toString()
// + new UUID("0000110100001000800000805F9B34F8", false).toString()
+ new UUID("0000110100001000800000805F9B34F9", false).toString()
+ ";name=serviceName";
private StreamConnectionNotifier m_service = null;
private ListenerThread m_listenerThread;
private DataOutputStream m_outStream;
public BluetoothService()
{
Open();
}
public void Open()
{
try
{
assert (m_service == null);
m_service = (StreamConnectionNotifier) Connector.open(serviceName);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void Start()
{
try
{
StreamConnection connection = (StreamConnection) m_service
.acceptAndOpen();
System.out.println("Connected");
m_listenerThread = new ListenerThread(connection);
Thread listener = new Thread(m_listenerThread);
listener.start();
m_outStream = new DataOutputStream(connection.openOutputStream());
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void Send(String message)
{
assert (m_listenerThread != null);
try
{
m_outStream.writeUTF(message);
m_outStream.flush();
System.out.println("Sent: " + message);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void Close()
{
try
{
m_service.close();
m_listenerThread.Stop();
m_listenerThread = null;
m_outStream.close();
m_outStream = null;
m_service = null;
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
class ListenerThread implements Runnable
{
private DataInputStream m_inStream;
private boolean m_isRunning;
public ListenerThread(StreamConnection connection)
{
try
{
this.m_inStream = new DataInputStream(connection.openInputStream());
m_isRunning = true;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
;
}
public void run()
{
while (m_isRunning)
{
try
{
assert (m_inStream != null);
if (m_inStream.available() > 0)
{
String message = m_inStream.readUTF();
System.out.println("Received command: " + message);
CommandManager.getInstance().Parse(message);
}
}
catch (IOException e)
{
System.err.println(e.toString());
}
}
}
public void Stop()
{
m_isRunning = false;
try
{
m_inStream.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
for restarting service I do:
BluetoothService::Close();
BluetoothService::Open();
BluetoothService::Start();
but seems I cannot reconnect. Maybe I should create service with different name?
Related
I have to create a simple rotating proxy application where 100 requests get evenly distributed to 10 devices. I've got the following structure:
WebServer with a Java-SocketServer running. All Android devices are connected to this Socket-Server to be able to know which devices are currently online and for determining which device should be used for the next request.
10 Android devices in different networks. They are connected to the Socket Server and are waiting for requests that should be forwarded to the remote address and then sent back to the SocketServer.
In easy words: I basically have to create an application similar like Honeygain, Peer2Profit or IPRoyal Pawns so that I can later do requests like this:
//Use "-x" to set Proxy-IP and Proxy-Port
curl -x ANDROID_DEVICE_IP:PORT -L https://www.google.com
I managed to have an always running proxy service in an Android application. It basically looks like this and just forwards HTTP-Requests from Port 1440 to the desired remote address and then sends the response back to the original client. The Proxy basically works fine.
public class ProxyServerThread extends Thread {
public static void main(String[] args) {
(new ProxyServerThread()).run();
}
public ProxyServerThread() {
super("Server Thread");
}
#Override
public void run() {
try (ServerSocket serverSocket = new ServerSocket(1440)) {
Socket socket;
try {
while ((socket = serverSocket.accept()) != null) {
(new Handler(socket)).start();
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
return;
}
}
public static class Handler extends Thread {
public static final Pattern CONNECT_PATTERN = Pattern.compile("CONNECT (.+):(.+) HTTP/(1\\.[01])", Pattern.CASE_INSENSITIVE);
private final Socket clientSocket;
private boolean previousWasR = false;
public Handler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
try {
String request = readLine(clientSocket);
System.out.println(request);
Matcher matcher = CONNECT_PATTERN.matcher(request);
if (matcher.matches()) {
String header;
do {
header = readLine(clientSocket);
} while (!"".equals(header));
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(clientSocket.getOutputStream(), "ISO-8859-1");
final Socket forwardSocket;
try {
forwardSocket = new Socket(matcher.group(1), Integer.parseInt(matcher.group(2)));
System.out.println(forwardSocket);
} catch (IOException | NumberFormatException e) {
e.printStackTrace(); // TODO: implement catch
outputStreamWriter.write("HTTP/" + matcher.group(3) + " 502 Bad Gateway\r\n");
outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
outputStreamWriter.write("\r\n");
outputStreamWriter.flush();
return;
}
try {
outputStreamWriter.write("HTTP/" + matcher.group(3) + " 200 Connection established\r\n");
outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
outputStreamWriter.write("\r\n");
outputStreamWriter.flush();
Thread remoteToClient = new Thread() {
#Override
public void run() {
forwardData(forwardSocket, clientSocket);
}
};
remoteToClient.start();
try {
if (previousWasR) {
int read = clientSocket.getInputStream().read();
if (read != -1) {
if (read != '\n') {
forwardSocket.getOutputStream().write(read);
}
forwardData(clientSocket, forwardSocket);
} else {
if (!forwardSocket.isOutputShutdown()) {
forwardSocket.shutdownOutput();
}
if (!clientSocket.isInputShutdown()) {
clientSocket.shutdownInput();
}
}
} else {
forwardData(clientSocket, forwardSocket);
}
} finally {
try {
remoteToClient.join();
} catch (InterruptedException e) {
e.printStackTrace(); // TODO: implement catch
}
}
} finally {
forwardSocket.close();
}
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
}
}
private static void forwardData(Socket inputSocket, Socket outputSocket) {
try {
InputStream inputStream = inputSocket.getInputStream();
try {
OutputStream outputStream = outputSocket.getOutputStream();
try {
byte[] buffer = new byte[4096];
int read;
do {
read = inputStream.read(buffer);
if (read > 0) {
outputStream.write(buffer, 0, read);
if (inputStream.available() < 1) {
outputStream.flush();
}
}
} while (read >= 0);
} finally {
if (!outputSocket.isOutputShutdown()) {
outputSocket.shutdownOutput();
}
}
} finally {
if (!inputSocket.isInputShutdown()) {
inputSocket.shutdownInput();
}
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
}
private String readLine(Socket socket) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int next;
readerLoop:
while ((next = socket.getInputStream().read()) != -1) {
if (previousWasR && next == '\n') {
previousWasR = false;
continue;
}
previousWasR = false;
switch (next) {
case '\r':
previousWasR = true;
break readerLoop;
case '\n':
break readerLoop;
default:
byteArrayOutputStream.write(next);
break;
}
}
return byteArrayOutputStream.toString("ISO-8859-1");
}
}
}
Here comes the Problem:
Everything works fine but only on the local network. I cannot manage to get this to work without port forwarding. Since all devices are on their mobile cellular data I need a way to be able to connect to the device anyway.
How do the mentioned apps manage to connect to the devices?
I need to limit the number of client that can connect to the server . I only want 3 clients that can connect not more.
I tried if else conditions. and some loops.
public class server {
ServerSocket ss;
boolean quite=false;
ArrayList<MultiServerConnection> OurDomainsConnections=new ArrayList<MultiServerConnection>();
public static void main(String[] args) {
new server();
}
public server() {
try {
//TODO use method to take this as an input from user)
ss=new ServerSocket(3333);//here we are using connection 3333 (change as you want
while(!quite)
{
Socket s=ss.accept();//when a connection to the domain is found we accept it
MultiServerConnection OurConnection = new MultiServerConnection(s,this);
OurConnection.start();//Start Thread
OurDomainsConnections.add(OurConnection);//add connection to our Domain Connection
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//make sure its bloody same with client it took my 15 min to realize that XD
}
}
public class MultiServerConnection extends Thread {
Socket s;
DataInputStream din;
DataOutputStream dout;
server ss;
boolean quite=false;
public MultiServerConnection(Socket OurSocket,server OurServer)
{
super("MultiServerConnection");//server connection thread
this.s=OurSocket;
this.ss=OurServer;
}
public void ServerOutClientIn(String OutText)
{
try {
long ThreadID=this.getId();
dout.writeUTF(OutText);
dout.flush();//this is because of a buffer error :<
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void ServerOutAllClientIn(String OutText)
{
for(int i=0;i<ss.OurDomainsConnections.size();i++)
{
MultiServerConnection Connection=ss.OurDomainsConnections.get(i);
Connection.ServerOutClientIn(OutText);
}
}
public void run()
{
try {
din=new DataInputStream(s.getInputStream());
dout=new DataOutputStream(s.getOutputStream());
while(!quite)
{
while(din.available()==0)
{
try {
Thread.sleep(1);//sleep if there is not data coming
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String ComingText=din.readUTF();
ServerOutAllClientIn(ComingText);
}
din.close();
dout.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class MultiClients extends Thread {
Socket s;
DataInputStream din;
DataOutputStream dout;
boolean quite=false;
public ClientData c;
public interface1 GUI;
public MultiClients(Socket OurMultiSocket, interface1 gui)
{
s=OurMultiSocket;
c=new ClientData();
GUI=gui;
}
public void ClientOutServerIn(String Text)
{
//write the line from console to server
try {
if(Text.equals("change channel"))
{
System.out.print("sending changing channel: "+Text+"\n");
dout.writeUTF(Text);
dout.flush();
}
else if(Text.equals("new user"))
{
System.out.print("sending new user: "+ Text+"\n");
dout.writeUTF(Text+":"+c.GetName()+"="+c.GetChannel());
dout.flush();
}
else
{
dout.writeUTF(c.GetChannel()+"="+this.getName()+": "+Text);
dout.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void SetClient(String channel,String Name)
{
c.SetName(Name);
c.SetChannel(channel);
}
public void run()
{
try {
din=new DataInputStream(s.getInputStream());
dout=new DataOutputStream(s.getOutputStream());
while(!quite)
{
try {
while(din.available()==0)
{
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//if there is something just show it on console
//and then go back and do the same
String reply=din.readUTF();
String Chan=ExtractChannel(reply);
String name=ExtractName(reply);
/*if (reply.equals("change channel"))
{
System.out.print("changing channel in body: "+reply+"\n");
//GUI.ClearDisplay();
setChangedChannel();
}*/
if(name.equals("new user"))
{
System.out.print("new user in body: "+reply+"\n");
//GUI.ClearDisplay();
setChannel(reply);
}
else
{
PrintReply(Chan,reply);
}
//System.out.println(reply);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
din.close();
dout.close();
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
din.close();
dout.close();
s.close();
} catch (IOException x) {
// TODO Auto-generated catch block
x.printStackTrace();
}
}
}
public void CloseClient()
{
try {
din.close();
dout.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String ExtractName(String x)
{
String[]Y=x.split(":");
return Y[0];
}
public String ExtractChannel(String X)
{
String[]Y=X.split("=");
return Y[0];
}
public void PrintReply(String Chan,String Rep)
{
if(c.GetChannel().equals(Chan))
{
String []Y=Rep.split("=");
GUI.setDisplay(Y[1]);
//System.out.println(Y[1]+"\n \n \n \n");
}
}
public void setChannel(String x)
{
String []Y=x.split(":");
String []Z=Y[1].split("=");
System.out.print("setting "+Z[0]+" channel to "+Z[1]+"\n");
GUI.setUserInChannel(Z[0]);
}
public void setChangedChannel()
{
GUI.setUserInChannel(c.GetName()+": "+c.GetChannel());
}
class ClientData
{
public String ClientName;
public String channel;
public void SetChannel(String Chan)
{
channel=Chan;
}
public void SetName(String name)
{
ClientName=name;
}
public String GetChannel()
{
return channel;
}
public String GetName()
{
return ClientName;
}
}
}
in this code. more than 5 user can can chat together. i only want to allow 3 user to connect and to chat.
You can use AtomicInteger as a counter to check how many clients you have already connected:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
public class server {
ServerSocket ss;
boolean quite=false;
ArrayList<MultiServerConnection> OurDomainsConnections=new ArrayList<MultiServerConnection>();
final AtomicInteger runningCount = new AtomicInteger(0);
final Integer limit = 3;
public static void main(String[] args) {
new server();
}
public server() {
try {
//TODO use method to take this as an input from user)
ss=new ServerSocket(3333);//here we are using connection 3333 (change as you want
while(!quite)
{
Socket s=ss.accept();//when a connection to the domain is found we accept it
if (runningCount.incrementAndGet() < limit){ //increment number of clients and check
MultiServerConnection OurConnection = new MultiServerConnection(s,this, runningCount::decrementAndGet);
OurConnection.start();//Start Thread
OurDomainsConnections.add(OurConnection);//add connection to our Domain Connection
} else {
runningCount.decrementAndGet();
s.close();
System.out.println("limit exceeded");
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//make sure its bloody same with client it took my 15 min to realize that XD
}
}
interface Callback {
void call();
}
class MultiServerConnection extends Thread {
Socket s;
DataInputStream din;
DataOutputStream dout;
server ss;
boolean quite=false;
final Callback callbackOnFinish;
public MultiServerConnection(Socket OurSocket,server OurServer, Callback callbackOnFinish)
{
super("MultiServerConnection");//server connection thread
this.s=OurSocket;
this.ss=OurServer;
this.callbackOnFinish = callbackOnFinish;
}
public void ServerOutClientIn(String OutText)
{
try {
long ThreadID=this.getId();
dout.writeUTF(OutText);
dout.flush();//this is because of a buffer error :<
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void ServerOutAllClientIn(String OutText)
{
for(int i=0;i<ss.OurDomainsConnections.size();i++)
{
MultiServerConnection Connection=ss.OurDomainsConnections.get(i);
Connection.ServerOutClientIn(OutText);
}
}
public void run()
{
try {
din=new DataInputStream(s.getInputStream());
dout=new DataOutputStream(s.getOutputStream());
while(!quite)
{
while(din.available()==0)
{
try {
Thread.sleep(1);//sleep if there is not data coming
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String ComingText=din.readUTF();
ServerOutAllClientIn(ComingText);
}
din.close();
dout.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
callbackOnFinish.call();
}
}
}
When a new connection is accepted runningCount is atomically increased and value is got by runningCount.incrementAndGet(). Then if value below the limit - new MultiServerConnection is created with a callback. The callback is used for decrementing a counter on exit. If counter equal or above the limit => socket will be closed and error message printed. It is good to have a message passed to the socket.
P.S. I have not reviewed your solution. I've just added the feture you requested.
My server closes after one clients disconnects,and I can write only one more message then it crashes.I wonder why,since I only close the client socket when it types "EXIT SERVER" .This is the exception it throws:
java.io.EOFException
This is my code :
import java.net.*;
import java.io.*;
public class ServerPeer extends Thread {
Socket _socket;
String username;
public ServerPeer(Socket _socket) {
this._socket = _socket;
}
public void sendMessage(String _username, String _message) throws IOException {
ObjectOutputStream _obj = new ObjectOutputStream(
_socket.getOutputStream());
_obj.writeObject(new Message(_username, _message));
_obj.flush();
}
public synchronized void run() {
try {
ObjectInputStream _ois = new ObjectInputStream(_socket.getInputStream());
Message _message;
while (_socket.isConnected()) {
_message = (Message) _ois.readObject();
String divide = _message.getAll().substring(0, _message.getAll().indexOf(":"));
username = divide;
Server.listofusers.add(username);
for (ServerPeer sp : Server.listofpeers) {
if (_message.getAll().contains("EXIT SERVER")) {
Server.listofpeers.remove(sp);
_socket.close();
}
if (_message instanceof PrivateMessage) {
PrivateMessage privm = (PrivateMessage) _message;
for (ServerPeer sp2 : Server.listofpeers) {
if (sp2.username.equals(privm.getReceiver())) {
sp2.sendMessage(divide, privm.getAll());
String priv = privm.getAll().replaceAll("/w", "");
System.out.println(priv);
break;
}
}
} else {
sp.sendMessage(divide, _message.getAll());
System.out.println(_message.getAll());
}
}
_ois = new ObjectInputStream(_socket.getInputStream());
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Server Class:
import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
static ServerConfig _svconfig = new ServerConfig();
public static ArrayList<ServerPeer> listofpeers = new ArrayList<ServerPeer>();
public static ArrayList<String> listofusers = new ArrayList<String>();
public static int i = 0;
// final static int _mysocket;
public static void main(String[] args) {
try {
final int _mysocket = _svconfig.getPORTNumber();
System.out.println("Wainting for clients.....");
ServerSocket _serversocket = new ServerSocket(_mysocket, _svconfig.getCLIENTSNumber());
while (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
Socket _clientsocket = _serversocket.accept();
ServerPeer _serverpeer = new ServerPeer(_clientsocket);
_serverpeer.start();
listofpeers.add(_serverpeer);
}
_serversocket.close();
} catch (MissingKeyException e) {
e.printStackTrace();
} catch (UnknownKeyException e) {
e.printStackTrace();
} catch (InvalidFormatException e) {
e.printStackTrace();
} catch (ConnectException e) {
e.printStackTrace();
} catch (BindException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (SocketException e) {
System.out.println("You have been disconnected");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
EDIT:
Exception thrown in the console of the client who disconnects:
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2328)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2797)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at ClientPeer.serverEcho(ClientPeer.java:35)
at ClientPeer.run(ClientPeer.java:44)
BUILD STOPPED (total time: 1 minute 26 seconds)
From what I can tell i'd guess your code is incorrect, but it hard to tell without more code.
At first glance it seems that if too many people connect to your server you just shut down the entire server not just those connections.
while (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
Socket _clientsocket = _serversocket.accept();
ServerPeer _serverpeer = new ServerPeer(_clientsocket);
_serverpeer.start();
listofpeers.add(_serverpeer);
}
_serversocket.close();
A better approach would be something like the following. If too many users try to connect, just close the users connection.
ServerSocket _serversocket = new ServerSocket(_mysocket, _svconfig.getCLIENTSNumber());
boolean alive = true;
while (alive) {
try {
//Keep accepting connection request
Socket clientRequest = _serversocket.accept();
//Check if too many user are connected
if (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
ServerPeer _serverpeer = new ServerPeer(_clientsocket);
_serverpeer.start();
listofpeers.add(_serverpeer);
}else{
//Reject connection if too many connected
clientRequest.close();
}
} catch (Throwable t) {
t.printStackTrace();
}
}
//When server dead close it down
_serversocket.close();
Hope this helps.
Your code must be exiting after the client thread is terminated, create a thread that has the server accept method that starts the client thread, something like this,
/**
*/
private class ServerListener extends Thread
{
/**
*/
public void run()
{
try
{
Socket clientSocket = socket.accept();
System.out.println("client connected => "+clientSocket.getInetAddress().getHostAddress());
ServerListener th = new ServerListener();
th.start();
ClientThread cth = new ClientThread(clientSocket);
cth.start();
clients.add(cth);
return;
}
catch (Exception e)
{
e.printStackTrace();
//Main.getInsatance().println(e);
//Main.getInstance().println("socket disconnected => "+clientSocket.getInetAddress().getHostAddress());
}
}
}
Hello dear programmers ,
I am trying to make a tic tac toe game using android, my android application contains several activities, one of these activities can the allows client to send a message to the server asking if X user wants to challenge, if the user accepts the challenge the server messages me and we both move forward to another activity.
My server is running as a regular java code on my PC, this is my server code :
public class Server {
ServerSocket serverSocket;
ArrayList<ServerThread> allClients = new ArrayList<ServerThread>();
public static void main(String[] args) {
new Server();
}
public Server() {
// ServerSocket is only opened once !!!
try {
serverSocket = new ServerSocket(6000);
System.out.println("Waiting on port 6000...");
boolean connected = true;
// this method will block until a client will call me
while (connected) {
Socket singleClient = serverSocket.accept();
// add to the list
ServerThread myThread = new ServerThread(singleClient);
allClients.add(myThread);
myThread.start();
}
// here we also close the main server socket
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ServerThread extends Thread {
Socket threadSocket;
String userName;
boolean isClientConnected;
InputStream input;
ObjectInputStream ois;
OutputStream output;
ObjectOutputStream oos; // ObjectOutputStream
public ServerThread(Socket s) {
threadSocket = s;
}
public void sendText(String text) {
try {
oos.writeObject(text);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
input = threadSocket.getInputStream();
ois = new ObjectInputStream(input);
output = threadSocket.getOutputStream();
oos = new ObjectOutputStream(output);
userName = (String) ois.readObject();
isClientConnected = true;
System.out.println("User " + userName + " has connected");
while (isClientConnected) {
String singleText = (String) ois.readObject();
System.out.println(singleText);
for (ServerThread t : allClients)
t.sendText(singleText);
// oos.writeObject(singleText);
}
// close all resources (streams and sockets)
ois.close();
oos.close();
threadSocket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I use the communication between clients in only two activies, both activites contain the same connectUser() code :
public class MenuActivity extends Activity {
public static final String HOST = "10.0.2.2";
public static final int PORT = 6000;
static ConnectThread clientThread;
boolean isConnected;
static boolean isOnline = false;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
runOnUiThread(new Runnable() {
public void run() {
connectUser();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void connectUser() {
clientThread = new ConnectThread();
clientThread.start();
}
class ConnectThread extends Thread {
InputStream input;
OutputStream output;
ObjectOutputStream oos;
Socket s;
public void sendText(String text) {
try {
oos.writeObject(text);
System.out.println(text);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
s = new Socket(HOST, PORT);
output = s.getOutputStream();
oos = new ObjectOutputStream(output);
oos.writeObject(un);
isOnline = true;
isConnected = true;
new ListenThread(s).start();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ListenThread extends Thread {
Socket s;
InputStream input;
ObjectInputStream ois;
public ListenThread(Socket s) {
this.s = s;
try {
input = s.getInputStream();
ois = new ObjectInputStream(input);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
while (isConnected) {
try {
final String inputMessage = (String) ois.readObject();
//do something with the message }
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
I use this code this code to send message to the server :
clientThread.sendText(user + " " + opponent + " play");
The problem is that when I create the connection at the first activity, then move to the second activity I create another connection , which means so far I am having two connections, same with other clients and then the server seems to return a timed out error.
My question is how to do a global client variable that is created once and can be used in each activity. I saw many suggestions like socket service or asyntask , but I need more direction and help
Thanks in advance.
Add a sub class of Application to your project and update application tag and add this class as android:name:
<application
android:name="com.your.app.MyApplication"
...
and then create a static reference to your Socket connection in MyApplication class:
private static Socket connection;
and then add a static method to access this object:
public static Socket getConnection() {
if( connection == null) {
// initialize connection object here
}
return connection;
}
Now you have a global object!
yet another java problem ...
got a client which should connect to a server via passive mode.
it seems to work fine, i get the ip adress and the port and the passivesocket says that it's ready.
but the passivesocket.getInputStream isn't ready at all - so i can't read from it and don't get the response to LIST.
can't figure out why, any suggestions?
public synchronized void getPasvCon() throws IOException, InterruptedException {
// Commands abholen
// IP Adresse holen
Thread.sleep(200);
String pasv = commands.lastElement();
String ipAndPort = pasv.substring(pasv.indexOf("(") + 1,
pasv.indexOf(")"));
StringTokenizer getIp = new StringTokenizer(ipAndPort);
// holt die IP
String ipNew = ""; // IP für den neuen Socket
for (int i = 0; i < 4; i++) {
if (i < 3) {
ipNew += (getIp.nextToken(",") + ".");
} else {
ipNew += (getIp.nextToken(","));
}
}
Integer portTemp1 = new Integer( getIp.nextToken(","));
Integer portTemp2 = new Integer (getIp.nextToken(","));
portNew = (portTemp1 << 8 )+ portTemp2;
System.out.println(">>>>> " + ipNew + ":" + portNew);
try {
pasvSocket = new Socket(ipNew, portNew);
System.out.println("Socket verbunden: "+ pasvSocket.isConnected());
} catch (UnknownHostException e) {
System.out.println("Host unbekannt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fromPasvServer = new BufferedReader(new InputStreamReader(
pasvSocket.getInputStream()));
Thread.sleep(2000);
System.out.println("Streams bereit: " + fromPasvServer.ready() + " | " );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
writePasvCommands = new PrintWriter(pasvSocket.getOutputStream(),
true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread.sleep(3000);
Thread pasvKonsole = new Thread(new PasvKonsole(this));
pasvKonsole.start();
}
public void LIST() throws IOException {
writeCommands.print("LIST\n");
writeCommands.flush();
}
public void run() {
try {
connect();
// getStatus();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
USER();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PASS();
try {
Thread.sleep(2000);
PASV();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
import java.io.IOException;
public class PasvKonsole extends Thread {
Client client;
public PasvKonsole(Client client) {
this.client = client;
}
public void run() {
System.out.println("========= PasvKonsole started");
while(true) {
try {
String lineP = client.fromPasvServer.readLine();
System.out.println("***" + lineP);
System.out.println("Ich bin da und tue auch was");
} catch (IOException e) {}
}
}
}
Added a Thread.Sleep and it works.