Handling all clients in a java Socket Server - android

I have a server and i am trying to send to all clients a specific input(string). My code is here:
serverSocket = new ServerSocket(SERVERPORT);
while (true)
{
// listen for incoming clients
Socket client = serverSocket.accept();
mClients.add(client);
boolean finished = false;
try
{
for (int i=0; i<mClients.size(); i++)
{
Socket well = mClients.get(i);
DataInputStream in = new DataInputStream(well.getInputStream());
PrintStream out = new PrintStream(well.getOutputStream());
// Print a message:
System.out.println("Client from : " + client.getInetAddress() + " port " + client.getPort());
// now get the input from the socket...
while(!finished)
{
String st = in.readLine();
// Send the same back to client
out.println(st);
// Write it to the screen as well
System.out.println(st);
// If the input was "quit" then exit...
if (st.equals("quit")) { finished = true; System.out.println("Thread exiting..."); }
}
}
As it seems i am doing something wrong. Anyway i am trying to store all the connected sockets to a vector and then send them the string received by one of them. Is this the right approach?

In the first while(true) statement, only listen for incoming connections and then create a separate thread to handle that client connection.
From there, you could add each outPutStream you create, within each thread, into an global ArrayList. Loop through the arrayList(create a method for this with a String Parameter) and write whatever message you want to within said method.
Check out this Oracle Tutorial on Socket Communication for help

Related

Async socket connection, Client GUI Hangs When Server is Disconnected TCP Communication

I am using Tcp Sockets For Communication Between CLR C++ (Server) to Android(Client) While using .Net For GUI.
While the data is communicated and received. Using a Background Worker in C++ Application
if(backgroundworker1->CancellationPending)
{
listenerSocket->Close(); // Listener Socket is Closed
netStream->Close();
serverSocket->Close();
serverSocket->Shutdown(SocketShutdown::Both);
e->Cancel;
break;
}
While in Android i am using Async Class for Execution and receiving text from socket to a Handler. While in Doinbackground Function i am using this code.
try
{
socket = new Socket(dstAddress, dstPort);
BufferedReader inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
do
{
try
{
if (!inputStream.ready())
{
if (message != null)
{
MainActivity.handler.obtainMessage(0, 0, -1,"Server: " + message).sendToTarget();
message = "";
}
}
int num = inputStream.read();
message += Character.toString((char) num);
Log.e(message,message);
}
catch (Exception classNot)
{
Log.e("Client TASK","classnot exception");
}
}
while (!message.equals("bye"));
inputStream.close();
socket.close();
}
I don't understand While am sending the Bye Message from the server and (Backgroundworker1->CancellationPending)
All server sockets are closed and Mobile Sockets are closed why is the UI Not Responding? Please Help..
The Problem was in Client in doinbackground Which calls the while loop again hence causing an exception because no data was received in the sockets and causing an exception. Finally added some sleep to the client that after some time the client query the server while if there is no message from the server the client shutdowns and shifted to postexecution function.

server socket multithreading confuses with the devices

I'm writing an Android app using sockets for communication. In a class called sever I accept clients (android devices) and open sockets for them.
Server side:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Socket socket = serverSocket.accept();
Client clientThread = new Client(socket);
System.out.println("New client: " + clientThread.getName());
new Thread(clientThread).start();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
After a succesful connection the user may create a group, which is like a room for number of clients to connect and play together.
The group creation is done here:
Server side:
Client:
private void client_create() {
this.mGroup = new Group();
mGroup.joinPlayer(this);
System.out.println("New group for: " + name);
}
Group:
public Group(int nClients){
// Clients in this group
this.clients = new ArrayList<Client>();
}
public void joinPlayer(Client player){
clients.add(player);
}
Client Side:
Connection handling:
try {
socket = new Socket(hostName, portNumber);
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
Listener listener = new Listener();
new Thread(listener).start();
} catch (IOException e) {
e.printStackTrace();
}
I ran this programm on 2 android devices and on my localhost as the server. After the connection was made, I tried creating 2 independent different groups. While debugging it all seems legit until I reached to a point where I lost it due to the 2 different running threads.
The odd thing that happened is that after the first group was created with the first client (clients contains the first device client object), and then the second group with the second player (clients contains the second device client object), the first group clients array contains the second client object (from the second device).
Have you got any thoughts on that? Did I do something wrong?
Figured it out.
Clients was mistakly defined as static, so I guess when accessing to the clients array of the static object it received the last one who was created.

android TCP client unable to display data sent from C Server via wi-fi

I'm kinda new to android socket programming. My android program simply connects to a server (written in c,executed in the console) and must display the content being sent from the server (something like "hi client"). I have textview's for displaying whether the connection is being established or not and another edittext for sending the client's message to the server. The system is connected via Wi-fi. The server is able to recieve messages from my android client but android client is not displaying the message sent by the server. The code snippet for the reading from server part is:
private TextView MsgFromServer; //defination
// here is the code for the connection and starting new thread etc
final BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
handler.post(new Runnable() {
#Override
public void run() {
try {
while((line=in.readLine())!=null){
MsgFromServer.append(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Also I tried doing something like this:
final BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
line=in.readLine().toString(); //string type
handler.post(new Runnable() {
#Override
public void run() {
MsgFromServer.setText(line);
}
}
both approaches are not working for me.The message I send from the client to the server reaches there properly whereas the other direction communication is not happening. Also I've tested my C server with a simple C client and the message passing is happening smoothly.
How does the client behave? Is it waiting at in.readLine() ?
Be sure the server sends "Hi client\n" (with the lineend).
in.readLines() only returns when a lineend \n is found.
Is the new Runnable running? If you change the code
a little to
try {
MsgFromServer.append("going to read a line..");
while((line=in.readLine())!=null){
MsgFromServer.append(line);
}
then do you see that?

Send keystrokes from android device to PC without "stutter"

I'm working on an android app that when a button in the app is pressed, sends a key stroke to a server listing on the PC. Everything is working fine expect for a problem of the output "stuttering" when the button is pressed rapidly. If on the client is press rapidly, the server will "stutter" and sometimes simply become unresponsive. The cod I'm using is extremely simple. To simple?
Server side:
ServerSocket welcomeSocket = new ServerSocket(6789);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
keyin = inFromClient.readLine();
robby.translateAndForward(keyin);
}
}
catch (Exception ex)
....
On the client
public class ImageBoundListener implements OnTouchListener {
private ImageView view;
private static PadClient client;
The On Touch Event handler
#Override
public boolean onTouch(View view, MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;;
if (client==null)
{
client=new PadClient();
}
if (action==MotionEvent.ACTION_DOWN)
{
client.sender("A");
}
Integer actionCode = action & MotionEvent.ACTION_MASK;
Log.d(actionCode.toString()," Event occured on: "+view.getTag());
return true;
}
}
The Actual send implementation
try{
Socket clientSocket = new Socket("192.168.1.104", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("Writing bytes to the server..");
outToServer.writeBytes(send);
clientSocket.close();
}
Not sure where to go from here...
There are several issues with your code:
Your code is opening connection every time button is pressed. If it is pressed rapidly - a lot of connections will be opened simultaneously between client and server.
It would be better to make one persistent connection and send all the data through it.
Also you can add some sort of buffering on the client side. I mean that data from several button presses will be combined into one data packet and sent to the server.
When dealing with communication problems between client and server - network I/O logging (what was sent and what was received on either side) is very important.
You server side can look like this:
try {
ServerSocket welcomeSocket = new ServerSocket(6789);
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
while(true) {
keyin = inFromClient.readLine();
Log.d("SERVER"," received: '" + keyin + "'");
robby.translateAndForward(keyin);
}
}
catch (Exception ex) {}

Problems sending and receiving data over TCP socket

I am having problems trying to use my android (Basic4Android) to communicate with my PC running a .net TCP server. I need to be able to have buttons that send 4byte commands to the server and receive back a response. When I run the program on the android the server does connect and receives the string "INFO", but then nothing else sends or receives until I restart the program and it only sends the command "INFO" again. I don't get any errors when I press the buttons to send commands, but the server never receives anything. The server is a Windows form multi-thread program written in VB.NET. I wrote a VB.NET client program that works that I can attach as an example of what I am trying to do. This is my first attempt at a Android application and so far I am just modifing the network examples I found in the tutorials.
The code is below...
Thanks
Sub Process_Globals
Dim Socket1 As Socket
End Sub
Sub Globals
Dim Button_ARM As Button
Dim Button_STAY As Button
Dim Button_AUTO As Button
Dim Button_OFF As Button
Dim Label_Received As Label
Dim Label_Sent As Label
Dim tr As TextReader
Dim tw As TextWriter
Dim sb As StringBuilder
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Alarm_Control")
Socket1.Initialize("Socket1")
Socket1.Connect("#.#.#.#" , 8000, 20000) 'My IP address goes here
End Sub
Sub Socket1_Connected (Successful As Boolean)
If Successful = False Then
Msgbox(LastException.Message, "Error connecting")
Return
End If
tr.Initialize(Socket1.InputStream)
tw.Initialize(Socket1.OutputStream)
tw.WriteLine("INFO")
Label_Sent.Text = "Sent INFO"
tw.Flush
sb.Initialize
sb.Append(tr.ReadLine)
Label_Received.Text = sb.ToString
'Socket1.Close
End Sub
Sub Button_ARM_Click
tw.WriteLine("O001")
tw.Flush
Label_Sent.Text = "Sent O001"
End Sub
Sub Button_STAY_Click
tw.WriteLine("O002")
tw.Flush
Label_Sent.Text = "Sent O002"
End Sub
Sub Button_OFF_Click
tw.WriteLine("O000")
tw.Flush
Label_Sent.Text = "Sent O000"
End Sub
How are you reading the data in the server side? Note that TextWriter.WriteLine writes a line terminated with chr(10). Make sure that you are not waiting for chr(13) and chr(10).
I am using networkStream.read and networkStream.write in a thread called by the listner. The vb.net client program work correctly with the vb.net server.
Public Sub handlerThread()
Dim handlerSocket As Socket
handlerSocket = alSockets(alSockets.Count - 1)
Dim networkStream As NetworkStream = New NetworkStream(handlerSocket)
Dim bytes(4) As Byte
networkStream.Read(bytes, 0, CInt(4)) ' Read the stream into 4-byte array
Dim clientdata As String = Encoding.ASCII.GetString(bytes)
Label_Received.Text = clientdata
Dim responseString As String = "Received " + clientdata
Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(responseString)
networkStream.Write(sendBytes, 0, sendBytes.Length)
Label_Sent.Text = responseString
handlerSocket = Nothing
End Sub
Chr(10) does not seem to be an issue here.
I'm having the same problem using this java server code:
import java.io.*;
import java.net.*;
public class ec192 {
public static void main(String[] args) throws IOException {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
echoSocket = new Socket("192.168.0.45", 2222);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to: 2222 taranis.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
}

Categories

Resources