Android application using Socket to send and receive messages: - java

I have an android application that I am attempting to use to send and receive messages to a server using socket connection.
I have had all manner of problems sending and receiving. I have been able to do one or the other, at no point both.
I was wondering if someone could help me with a simple exercise that I can compile using BufferedReader and PrintWriter to do so.
I appreciate any help as I am at the point of giving up.
Thanks in advance.... Below are a few shots of what I have tried (Though they are irrelevant to this question, I hope it shows that I have tried before asking here).
private OnClickListener sendClickListener = new OnClickListener(){
public void onClick(View arg0) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}};
public class ClientThread implements Runnable {
public void run() {
try {
EditText dstAddress = (EditText) findViewById(R.id.destinationAddress);
EditText dstMessage = (EditText) findViewById(R.id.messageToTranslate);
EditText dstPort = (EditText) findViewById(R.id.destinationPort);
String address = dstAddress.getText().toString();
String message = dstMessage.getText().toString();
int port = Integer.parseInt(dstPort.getText().toString());
InetAddress serverAddr = InetAddress.getByName(address);
Log.d(".Coursework", "C: Connecting...");
Socket socket = new Socket(serverAddr, port);
connected = true;
while (connected) {
try {
EditText dstTranslation = (EditText) findViewById(R.id.returnedTranslation);
dstTranslation.setText("help me");
Log.d(".Coursework", "C: Sending command.");
PrintWriter out;
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(language);
out.println(message);
Log.d("ClientActivity", "C: Sent.");
//BufferedReader in;
//in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//String translation = in.readLine();
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
connected = false;
}
}
public class ClientConnection {
String address, language, message;
int portNumber;
Socket clientSocket = null;
public ClientConnection(String lan, String mes, String add, int pn) throws IOException{
address = add;
portNumber = pn;
language = lan;
message = mes;
}
public String createAndSend() throws IOException{
// Create and connect the socket
Socket clientSocket = null;
clientSocket = new Socket(address, portNumber);
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// Send first message - Message is being correctly received
pw.write(language+"\n");
pw.flush();
// Send off the data
// Send the second message - Message is being correctly received
pw.write(message+"\n");
pw.flush();
pw.close();
// Send off the data
// NOTE: Either I am not receiving the message correctly or I am not sending it from the server properly.
String translatedMessage = br.readLine();
System.out.print(translatedMessage);
br.close();
//Log.d("application_name",translatedMessage); Trying to check the contents begin returned from the server.
return "Say What??";
}
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerConnection {
public static void main(String[] args) throws Exception {
// Delete - Using while loop to keep connection open permanently.
boolean status = false;
while( !status){
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
// Delete - Working as of here, connection is established and program runs awaiting connection on 4444
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String language = br.readLine();
String message = br.readLine();
// Test - Works
System.out.println(language);
// Test - Works
System.out.println(message);
// Delete - Working as of here, both messages are passed and applied. Messages are received as sent from client.
TranslateMessage tm = new TranslateMessage();
String translatedMessage = tm.translateMessage(language, message);
// NOTE: This seems to be where I am going wrong, either I am not sending the message correctly or I am not receiving it correctly..
// PrintWriter writer = new PrintWriter(new BufferedOutputStream(clientSocket.getOutputStream()));
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(),true);
// Send translation back
System.out.println(translatedMessage);
pw.write(translatedMessage+"\n");
pw.write("Return test \n"); // Test message!
pw.flush();
// Send off the data
pw.close();
br.close();
clientSocket.close();
serverSocket.close();
}
}
}

I simply neglected to close the socket connection on the client side. So whilst I doubt what I have done is a model answer to my own question it works of included.

Related

Sending a Message to Multiple Clients from One Server Simultaneously?

I am currently working on a TCP Sockets program in Java in which two or more separate clients connect to a single server, and that server will send a message to both of these connected clients simultaneously.
I've tried to work through the code multiple times, but I can't quite seem to be able to have one message be sent to both clients.
Below is a reduced version of my entire code, condensed down to just the issue I'm having.
I've also included a video, just to save you the effort of having to copy and run my code!
[STREAMABLE LINK]
When one client is connected, I just have to write one message in the server, press send, and it shows up in the client.
When two clients are connected, I have to write two messages in the server and press send twice, and one message goes to one client and the other to the next client.
How can I make it so I only send one message from the server that goes to all clients?
I greatly appreciate any and all help.
SERVER CODE:
import java.io.*;
import java.net.*;
import java.util.*;
// Server class
class Server {
public class countLogic {
public static int client_count = 0;
}
public static void main(String[] args) {
System.out.println("[SERVER]");
ServerSocket server = null;
try {
server = new ServerSocket(1234);
server.setReuseAddress(true);
while (true) {
Socket client = server.accept();
countLogic.client_count++;
System.out.println("Client ("+countLogic.client_count+") connected: " + client.getInetAddress().getHostAddress());
ClientHandler clientSock = new ClientHandler(client);
new Thread(clientSock).start();
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (server != null) {
try {
server.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
// ClientHandler class
private static class ClientHandler implements Runnable {
private final Socket clientSocket;
public ClientHandler(Socket socket)
{
this.clientSocket = socket;
}
public void run()
{
PrintWriter out = null;
BufferedReader in = null;
try {
Scanner sc = new Scanner(System.in);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = null;
while (true) {
line = sc.nextLine();
out.println(line);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
clientSocket.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
CLIENT CODE:
import java.io.*;
import java.net.*;
import java.util.*;
// Client class
class Client {
// driver code
public static void main(String[] args)
{
System.out.println("[CLIENT 1]");
try (Socket socket = new Socket("localhost", 1234)) {
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Scanner sc = new Scanner(System.in);
String line = null;
while (!"exit".equalsIgnoreCase(line)) {
System.out.println("Server: "+ in.readLine());
}
// closing the scanner object
sc.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}

Handler thread hanging on reading in

I am trying to set up a server with a client and a handler. The client should ask for a string from the user. This should then be written to an OutputStream, get read in by the handler which then saves the string to its own OutputStream before passing it back to the client. I know that this program is completely pointless, I am just trying to get my head around how servers, clients and handlers work.
Here is my code so far:
Server
public class Server {
public static void main (String args[]) throws IOException {
int port = 8080;
ServerSocket server = new ServerSocket(port);
while (true) {
System.out.println("Waiting for client...");
Socket client = server.accept();
System.out.println("Client from "+client.getInetAddress()+" connected.");
Handler handler = new Handler(client);
handler.run();
}
}
}
Handler
class Handler extends Thread {
private Socket client;
public Handler(Socket c) {
client = c;
}
public void run() {
try {
Thread.sleep(3000);
System.out.println("1");
PrintWriter out = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
BufferedReader in =
new BufferedReader(new InputStreamReader(client.getInputStream(),
"UTF-8"));
System.out.println("2");
String message = in.readLine();
System.out.println("4");
System.out.println("5");
out.println(message);
out.flush();
client.close();
System.out.println("Finish");
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Client
public class Client {
public static void main (String args[]) throws IOException {
Socket server = new Socket("127.0.0.1", 8080);
System.out.println("Attempting connection...");
Scanner scan = new Scanner (System.in);
System.out.println("Please enter a string:");
String message = scan.next();
PrintWriter out = new PrintWriter(new OutputStreamWriter(server.getOutputStream()));
BufferedReader in =
new BufferedReader(new InputStreamReader(server.getInputStream(),
"UTF-8"));
out.println(message);
String messageReturn = in.read();
scan.close();
System.out.println("Server said: " + messageReturn);
in.close();
out.close();
}
}
The problem is that the handler seems to hang when it tries to read the message in. This problem seems similar to the one presented here: Socket problem - readline won't work properly
But this solution isn't working for me. I have tried using objectInputStreams instead of my current solution, but this didn't work either.
I doubt whether your client code will compile. The return type for this is int.
String messageReturn = in.read();
Anyway, this should work:
package network;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main (String args[]) throws IOException {
Socket server = new Socket("127.0.0.1", 9890);
System.out.println("Attempting connection...");
Scanner scan = new Scanner (System.in);
System.out.println("Please enter a string:");
String message = scan.next();
PrintWriter out = new PrintWriter(new OutputStreamWriter(server.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream(), "UTF-8"));
out.println(message);
// NOTE this
String messageReturn = in.readLine();
scan.close();
System.out.println("Server said: " + messageReturn);
in.close();
out.close();
}
}
Note Port has been changed.
Server Output
Waiting for client...
Client from /127.0.0.1 connected.
1
Client Output
Attempting connection...
Please enter a string:
Hello
The problem might be that you do not send an escape sequence with your response. ReadLine() waits till it gets an escape. Try sending a "\n" with your response. There is an article about problems using readLine() and println() with sockets. It also shows how to solve it.
ReadLine() / Println() and sockets

ServerSocket cannot read input from Client

I'm new to socket programming and I'm just trying out a few things. What I'm trying to do is have a Client that reads a text file, saves the lines from that file in an ArrayList and then send the lines to the Server. This is my code. The connection is successfully established, but when the server tries to read from his BufferedReader, it doesn't get anything:
Server:
import java.io.*;
import java.net.*;
public class Server extends Thread{
ServerSocket sock = null;
Socket client_sock = null;
PrintWriter out = null;
BufferedReader in = null;
Server(int port){
try{
sock = new ServerSocket(port);
}catch(IOException e){
System.out.println("Couldn't create server socket");
e.printStackTrace();
}
}
public void run(){
while (true){
try{
client_sock = sock.accept();
System.out.println("Successfully connected to client" + client_sock);
System.out.println(client_sock.getOutputStream());
System.out.println(client_sock.getInputStream());
out = new PrintWriter(client_sock.getOutputStream(),true);
//System.out.println(out);
in = new BufferedReader(new InputStreamReader(client_sock.getInputStream()));
//System.out.println(in);
System.out.println("Trying to read line sent from client:");
String l;
try{
l = in.readLine();
System.out.println(l);
}catch(IOException e){
System.out.println("Couldn't read line from client");
e.printStackTrace();}
}catch(IOException e){
e.printStackTrace();
break;
}
}
}
public static void main(String[] args){
//Thread t = new Server(Integer.parseInt(args[0]));
//t.start();
Server serv = new Server(10239);
System.out.println(serv.sock);
serv.run();
}
}
Client:
import java.net.*;
import java.io.*;
import java.util.*;
public class Client {
Socket sock = null;
OutputStream toServer = null;
PrintWriter out = null;
InputStream fromServer = null;
BufferedInputStream in = null;
Client(int port){
try{
sock = new Socket("localhost",port);
//System.out.println(sock.getPort());
//System.out.println(sock.getOutputStream());
//System.out.println(sock.getInputStream());
//toServer = sock.getOutputStream();
//System.out.println(sock.getOutputStream());
out = new PrintWriter(sock.getOutputStream());
//System.out.println(out);
//fromServer = sock.getInputStream();
in = new BufferedInputStream(sock.getInputStream());
//System.out.print(in);
}catch(UnknownHostException ue){
System.out.println("Host not known");
}
catch(IOException e){
e.printStackTrace();
}
}
public static void main(String[] args){
Client client = new Client(Integer.parseInt(args[0]));
File f = new File("/Users/--------/Desktop/socket_test.txt");
BufferedReader f_in = null;
try{
f_in = new BufferedReader(new FileReader(f));
}catch(IOException e){
System.out.println("Cannot create FileReader for test file");
}
String line;
ArrayList<String> text = new ArrayList<String>();
try{
while ((line = f_in.readLine()) != null){
text.add(line);
}
}catch(IOException e){
e.printStackTrace();
}
//System.out.println("first line of file");
//System.out.println(text.get(0));
for (String l : text){
System.out.println("Sent the following line:");
System.out.println(l);
client.out.println(l);
}
}
}
This is the output I get for the Client:
Sent the following line:
Similar to the previous constructor
Sent the following line:
the InetAddress parameter specifies
Sent the following line:
the local IP address to bind to.
Sent the following line:
The InetAddress is used for servers that
Sent the following line:
may have multiple IP addresses
Sent the following line:
allowing the server to specify which of
Sent the following line:
its IP addresses to accept client requests on
and this for the Server:
ServerSocket[addr=0.0.0.0/0.0.0.0,localport=10239]
Successfully connected to clientSocket[addr=/127.0.0.1,port=58285,localport=10239]
Trying to read line sent from client:
null
I can't find the reason why this doesn't work, can anybody help me please?
Try to flush the stream after each line :
client.out.println(l);
client.out.flush();

the ReadLine doesnt wait for input

I have a socket client sending text to a socket server but the ReadLine doesnt seem to wait to receive a line before proceeding. Here is the of the server receiving the text:
public void run() {
try {
serveurSocket = new ServerSocket(PORT_ID);
connexionSocket = serveurSocket.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(connexionSocket.getInputStream()));
PrintWriter writer = new PrintWriter(connexionSocket.getOutputStream(), true);
messageRecu = "";
while (true) {
messageRecu = reader.readLine();
messageRecu = messageRecu.toUpperCase();
writer.println(messageRecu);
}
//reader.close();
//writer.close();
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
After establishing the socket between client and server, the execution halts at reader.readLine until I send manually a string thru the socket. Which is normal and wanted. Codes resumes and its fine until its loops back to reader.ReadLine() where it will read a "null" line instead of waiting for input from the socket like it did the first time... this will obviously mess up the next command to uppercase. So how can I fix this?
EDIT: I'll add the client side if that can help understand.
public class ClientSocket {
private Socket clientSocket;
public boolean isClosed() { return clientSocket.isClosed(); }
public boolean connectToSocket (String ip, int port) {
try {
clientSocket = new Socket(ip, port);
return true;
}
catch (IOException e) {
System.out.println(e);
return false;
}
}
public String sendToServer(String messageClient) {
String messageRecu = "";
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);
writer.println(messageClient);
messageRecu = reader.readLine();
reader.close();
writer.close();
return messageRecu;
}
catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
return messageRecu;
}
}
}
A button press will call "connectTosocket" to initiate the socket. A second button when pressed will send the content of a textfield using "sendToServer".
Server does receive the message and return it capitalized but I wish for the socket to remain open with the server and if I send an other string for the same sequence to happen. Not even sure it can be done :(
According to the documentation of BufferedReader#readLine, a null is returned if the end of stream has been reached.
Change your reading loop to :
while ((messageRecu = reader.readLine()) != null) {
messageRecu = messageRecu.toUpperCase();
writer.println(messageRecu);
}
//Get out of the loop when the end of stream is reached.
As per Reading from and Writing to a Socket chapter of the Java tutorial.
As a side note, while(true) loops are not really appreciated.
The "null" signals for end of connection from the client side - which is why the connection disconnects. If you want to support multiple requests, you should run a new ServerSocket.accept() each time and wait for a new client to connect.
KKMultiServer class:
import java.net.*;
import java.io.*;
public class KKMultiServer {
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.err.println("Usage: java KKMultiServer <port number>");
System.exit(1);
}
int portNumber = Integer.parseInt(args[0]);
boolean listening = true;
try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
while (listening) {
new KKMultiServerThread(serverSocket.accept()).start();
}
} catch (IOException e) {
System.err.println("Could not listen on port " + portNumber);
System.exit(-1);
}
}
}
KKMultiServerThread class:
import java.net.*;
import java.io.*;
public class KKMultiServerThread extends Thread {
private Socket socket = null;
public KKMultiServerThread(Socket socket) {
super("KKMultiServerThread");
this.socket = socket;
}
public void run() {
try (
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
) {
String inputLine, outputLine;
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye"))
break;
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
You can read more about sockets in Oracle tutorials

Java UDP server

I am new to Java programming and I am trying to create a UDP server. When I compile the code it says it could not listen to port 4722 and I would like to know why. Below is the code. I would be grateful for any advice.
import java.net.*;
import java.io.*;
public class Server
{
public static void main(String[] args) throws IOException
{
DatagramSocket serverSocket = new DatagramSocket(4722);
Socket clientSocket = null;
byte[] receiveData = new byte[1024];
byte[] sendData = new byte [1024];
boolean command = true;
try
{
serverSocket = new DatagramSocket(4722);
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
System.out.println("Waiting for client...");
}
catch (IOException e)
{
System.err.println("Could not listen on port: 4722.");
System.exit(1);
}
DatagramPacket packet = new DatagramPacket (sendData,sendData.length,4722);
serverSocket.send(packet);
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine, outputLine;
mathematicalProtocol bbm = new mathematicalProtocol();
outputLine = bbm.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null)
{
if(inputLine.equals("Bye."))
break;
outputLine = bbm.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
You are initializing serverSocket and then making a new DatagramSocket on the same port again (and you can't do that as it's already bound on the first DatagramSocket). I.e. remove the following line:
serverSocket = new DatagramSocket(4722);
Here is a complete example of client/server UDP communication.
The server read data from a file and send each line to the client.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
* #author nono
*
*/
public class UDPFileSender {
static class Client implements Runnable {
// Reception socket
private DatagramSocket socket;
// UDP packet to receive data into
private DatagramPacket packet;
// Flag for initialisation
private boolean failedInit = true;
/**
* Client constructor.
* #param receptionPort
* #param packetMaxLenght
*/
public Client(int receptionPort, int packetMaxLenght) {
try {
// Create the socket using the reception port
this.socket = new DatagramSocket(receptionPort);
// Init the packet
this.packet = new DatagramPacket(new byte[packetMaxLenght],packetMaxLenght);
this.failedInit = false;
} catch (SocketException e) {
//Port already used or other error
e.printStackTrace();
}
}
#Override
public void run() {
if(failedInit){
return;
}
// Loop undefinitly
while(true){
try {
System.out.println("Waiting for packet...");
// Wait for packet
socket.receive(packet);
// Assuming you are receiving string
String msg = new String(packet.getData());
System.out.println("Received : " + msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
try {
int port = 4722;
//Start a client that can listen
new Thread(new Client(port,1024)).start();
// Creaete a reader
BufferedReader reader = new BufferedReader(new FileReader("File.txt"));
//Create a socket
DatagramSocket socket = new DatagramSocket();
// Create a packet
byte[] data = new byte[1024]; // Max length
DatagramPacket packet = new DatagramPacket(data, data.length);
// Set the destination host and port
packet.setAddress(InetAddress.getByName("localhost"));
packet.setPort(port);
String line = null;
while((line = reader.readLine()) != null){
//Set the data
packet.setData(line.getBytes());
//Send the packet using the socket
System.out.println("Sending : " + line);
socket.send(packet);
Thread.sleep(200);
}
//Close socket and file
reader.close();
socket.close();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
If your file contains :
Hello
World
You should see :
Waiting for packet...
Sending : Hello
Received : HelloWaiting for packet...
Sending : World
Received : World
Waiting for packet...

Categories

Resources