Android TCP server recieves all data on application exit - java

I'm having the following TCP client code:
public static void register(InetAddress ip, int port, String name) {
try {
Socket clientSocket = new Socket(ip, port);
send("reg:" + name);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void send(String str) {
try {
String sentence = str;
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(sentence);
} catch (IOException e) {
Log.e("CONNECT", e.getMessage());
}
}
They both are called in onClicks and i know that for sure.
I also have the following Server code:
public static void main(String argv[]) throws Exception {
String clientSentence;
ServerSocket welcomeSocket = new ServerSocket(9876);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
outToClient.writeBytes("msg: Hello! kalin pedro");
}
}
When trying to send data to the server i don't get an exception, i also know that I'm connected to it because the application is crashing when i terminate the server application. The problem is that the server doesn't receive anything until i terminate the client application. Everything that i have tried to send until that moment is all received from the server at once. I looked at the network activity tab provided by Android Studio and there is a change when sending data, the server just doesn't receive it(or at least i don't see it receive it) until i terminate the client application.

Related

Java Socket connected but can't sent message by OutputStream.write() but PrintStream will work

I'm an amateur in java socket programming. As I say in title, When I using PrintStream for socket output,it works;but it doesn't work if I using simply OutputStream.
I know the the client connected to the server cause' the server got the info of the client.So I think there must be something wrong with I/O stream, not the socket connection.
btw, I even use the flush() method for OutputStream.I think flush() will force to send all bytes, but it seems like it didn't work.
The Client Code:#line 12:
public class Clinet {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("==========Client============");
Socket socket = new Socket("localhost", 8888);// Server's addr and port
socket.setSoTimeout(3000);
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
String msgToSent = "Hello TCP";
outputStream.write(msgToSent.getBytes());
outputStream.flush();// FIXME:why flush() didn't work?why msg wasn't sent.
// read from socket input
String receivedMsg = new String(inputStream.readAllBytes());
System.out.println(receivedMsg);
socket.close();
}
}
When I using a filter stream like PrintStream,the msg can be sent to server.
The Server Code: if using PrintStream it will work perfectly with the Client:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {
Socket client = serverSocket.accept();
new Thread(new ServerHandler(client)).start();
}
}
}
class ServerHandler implements Runnable {
private Socket client;
ServerHandler(Socket client) {
this.client = client;
}
#Override
public void run() {
try {
InetAddress clientAddr = client.getInetAddress();
int clientPort = client.getPort();
System.out.println("client connected # " + clientAddr + ":" + clientPort);
InputStream inputStream = client.getInputStream();
OutputStream outputStream = client.getOutputStream();
while (true) {
String msg = new String(inputStream.readAllBytes());// FIXME: Why Server didn't receive Client's msg?
System.out.print("/" + clientAddr + "#" + clientPort + " : ");
System.out.println(msg);
String reply = "I received " + msg.length() + " words.";// return how many words the server got.
outputStream.write(reply.getBytes());
outputStream.flush();// flush to ensure send all msg,but seems doesn't work
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Socket won't accept the strings

This is my code:
public class EchoServer {
ServerSocket ss;
Socket s;
DataInputStream din;
DataOutputStream dout;
public EchoServer()
{
try
{
System.out.println("server started");
//ss = new ServerSocket(0);
//System.out.println("listening on port: " + ss.getLocalPort());
ss = new ServerSocket(49731);
s = ss.accept();
System.out.println(s);
System.out.println("connected");
din = new DataInputStream(s.getInputStream());
dout = new DataOutputStream(s.getOutputStream());
Server_chat();
ss.close();
}
catch(Exception e)
{
System.out.println(e);
}
}
public static void main(String[] args) {
new EchoServer();
}
public void Server_chat() throws IOException {
String str;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in ));
do
{
System.out.println("enter a string");
str = br.readLine();
System.out.println("str " + din.readUTF());
dout.flush();
}
while(!str.equals("stop"));
}
}
I verified 49731 port by passing port no. 0 earlier and got this port.
When I run the above code on Netbeans the output shows "server started" and then it keeps on running even though it should show connected and rest of the input I provide.
And then it keeps on running even though it should show connected and
rest of the input I provide.
Why it should go on printing 'connected'?
s=ss.accept();
In this line you are: listens for a connection to be made to this socket and accepts it. The
method blocks until a connection is made.
accept method will wait for a client that connect to him. So you need to provide a client that connect to the server. Otherwise he'll wait forever!
For some examples about how to use socket in java see here and here.
For more about accept() read here

Socket Connection on Java, specify IP

I'm working on a program where multiple clients need to interact with a remote server.
I've tested it locally and everything's ok (sort of, more on that later), but I can't understand how to set a remote IP.
I read Socket's API and also InetAddress' API. Is this the right way to do it? How does Java deal with IPs? There are not just simple Strings as on the localhost case, am I right?
This is my code:
Client:
public class Client {
final String HOST = "localhost";
final int PORT = 5000;
Socket sc;
DataOutputStream message;
DataInputStream istream;
public void initClient() {
try {
sc = new Socket(HOST, PORT);
message = new DataOutputStream(sc.getOutputStream());
message.writeUTF("test");
sc.close();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
Server:
public class Server {
final int PORT = 5000;
ServerSocket sc;
Socket so;
DataOutputStream ostream;
String incomingMessage;
public void initServer() {
try {
sc = new ServerSocket(PORT);
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
}
BufferedReader input;
while(true){
try {
so = new Socket();
System.out.println("Waiting for clients...");
so = sc.accept();
System.out.println("A client has connected.");
input = new BufferedReader(new InputStreamReader(so.getInputStream()));
ostream = new DataOutputStream(so.getOutputStream());
System.out.println("Confirming connection...");
ostream.writeUTF("Successful connection.");
incomingMessage = input.readLine();
System.out.println(incomingMessage);
sc.close();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
}
Also, I'm dealing with some troubles on my local tests.
First of all, some times I get the following result:
Waiting for clients...
A client has connected.
Confirming connection...
Error: Software caused connection abort: recv failed
Though some other times it works just fine. Well, that first connection at least.
Last question:
When I try to send a message from the server to the client, the program enters in an infite loop and need to be closed manually. I'm adding this to the code to do so:
fromServerToClient = new BufferedReader(new InputStreamReader(sc.getInputStream()));
text = fromServerToClient.readLine();
System.out.println(text);
Am I doing it right?
Thanks.
Instead of using
String host = "localhost";
you can use something like
String host = "www.ibm.com";
or
String host = "8.8.8.8";
this is how you would usually implement a Server:
class DateServer {
public static void main(String[] args) throws java.io.IOException {
ServerSocket s = new ServerSocket(5000);
while (true) {
Socket incoming = s.accept();
PrintWriter toClient =
new PrintWriter(incoming.getOutputStream());
toClient.println(new Date());
toClient.flush();
incoming.close();
}
}
}
And following would be As Client:
import java.util.Scanner;
import java.net.Socket;
class DateClient {
public static void main(String[] args) throws java.io.IOException
{
String host = args[0];
int port = Integer.parseInt(args[1]);
Socket server = new Socket(host, port);
Scanner scan = new Scanner( server.getInputStream() );
System.out.println(scan.nextLine());
}
}
You should consider doing this in threads. Right now multiple users can't connect to the server at once. This means that they have to queue for connection to the server resulting in very poor performance.
Normally you receive the client and instantiate a new thread to handle the clients request. I only have exampls in C# so i won't bother you with that, but you can easily find examples on google.
eg.
http://www.kieser.net/linux/java_server.html

How to distinguish between multiple clients in client/server app

i am creating a simple client/server app
and was able to connect multiple clients to single server.
i referred to this link client/server simple app demo
my problem is that now,i want to return some response from server to client
based on its client/ip address.
eg. if 192.123.1.1 connects the response should be xml
if 192.123.1.2 connects the response should be json.
is it possible to do?? any help will be appreciated
here is my simple server code:
public class ChatServer implements Runnable
{
private ServerSocket server = null;
private Thread thread = null;
private ChatServerThread client = null;
public ChatServer(int port)
{ try
{ System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
start();
}
catch(IOException ioe)
{ System.out.println(ioe); }
}
public void run()
{ while (thread != null)
{ try
{ System.out.println("Waiting for a client ...");
addThread(server.accept());
}
catch(IOException ie)
{ System.out.println("Acceptance Error: " + ie); }
}
}
public void addThread(Socket socket)
{ System.out.println("Client accepted: " + socket);
client = new ChatServerThread(this, socket);
try
{ client.open();
client.start();
}
catch(IOException ioe)
{ System.out.println("Error opening thread: " + ioe); }
}
public void start()
public void stop()
public static void main(String args[])
I think instead of ip check the client should ask for the type of data they want. I am not sure why you require a check on ip. But in future if you all more clients then you have to change the server code every time. Better to define the format in the client so that client can ask for data of specific type.
Not very sure about your requirement.
There is an API call Socket.getRemoteSocketAddress().toString() to get the caller IP
Socket clientSocket =server.accept();
System.out.println(" client ip address =" +clientSocket.getRemoteSocketAddress().toString());
-- once you obtained clientSocket, use below sample to write back
Socket clientSocket =server.accept();
String returMessage ="Hello from Server ";
if (clientSocket.getRemoteSocketAddress().toString().equals("192.168.1.3")){
returMessage=returMessage +" welcome browser";
}
else if(clientSocket.getRemoteSocketAddress().toString().equals("192.168.1.4")){
returMessage=returMessage +" welcome tablet";
}
OutputStream os = clientSocket .getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returMessage);
System.out.println("Message sent to the client is "+returMessage);
bw.flush();
-- To read from client
InputStream is = clientSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String data = br.readLine();
System.out.println("Message received from client is "+data);
if("send_players".equals(data)){ // reading data you would need to finetune
//write playerlist
}

Java Client-Server application pipe not working on child thread

I have a client and a server. The client binds a socket on a specific port, the server sends back a new port to the client and the client should bind a new socket on the new port number.
From the main server thread, I start a thread that sends a message to the client once the server is ready and is listening to the new port, so that the client can attempt to connect to the new port. The pipe from the child thread is not sending the message to the client.
So both client and server just freeze, it seems like a deadlock, but im not sure. This line of code in the client: System.out.println("FROM SERVER: " + inMsg_rport); is not executing.
Server Code:
class server
{
public static void main(String argv[]) throws Exception
{
String newPort;
ServerSocket serverSocket = null;
Socket clientSocket = null;
try
{
serverSocket = new ServerSocket(5555);
clientSocket = serverSocket.accept();
DataOutputStream serverOut =
new DataOutputStream(clientSocket.getOutputStream());
int r_port = 5556;
Thread appThread = new Thread(new serverApp(serverOut, r_port));
appThread.start();
}
catch(IOException e)
{
System.out.println(e);
}
}
static class serverApp implements Runnable
{
DataOutputStream serverOut;
int nPort;
public serverApp(DataOutputStream servO, int r_port)
{
this.serverOut = servO;
this.nPort = r_port;
}
#Override
public void run()
{
ServerSocket serverSocket = null;
Socket clientSocket = null;
try
{
serverSocket = new ServerSocket(nPort);
serverOut.writeBytes(sr_port);
clientSocket = serverSocket.accept();
}
catch(IOException e)
{
System.out.println(e);
}
}
}
}
Client code:
class client {
public static void main(String argv[]) throws Exception
{
String serverIp = argv[0];
String msg = argv[2];
int port = Integer.parseInt(argv[1]);
Socket clientSocket = new Socket(InetAddress.getByName(serverIp), port);
BufferedReader clientIn =
new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()));
String inMsg_rport = clientIn.readLine();
System.out.println("FROM SERVER: " + inMsg_rport);
int r_port = Integer.parseInt(inMsg_rport);
clientSocket.close();
System.out.println("Closed connection");
Socket new_clientSocket = new Socket(InetAddress.getByName(serverIp), r_port);
}
}
readLine() in your client is a blocking call, waiting for an end-of-line character
http://docs.oracle.com/javase/6/docs/api/java/io/BufferedReader.html#readLine()
You aren't sending an end of line character. You're using a DataOutputStream in your server and sending raw bytes.
Don't use a DataOutputStream in your server; I don't think that's really what you're looking for. Just send the port number as text with an end of line character and be done with it.

Categories

Resources