i'm using TCP socket to send and receive data from the same socket in the same activity through client server thread, the purpose of that is to send a string to other device and that string will trigger a notification once the other device receives it then that device will replay with something like dismiss or accepted, the problem that i'm having is after sending the string the other device receives it and send the dismiss or accepted String but my divice doesn't receive that string i guess there is a problem in my ServerThread be aware that the server thread and client thread are in the same activity used as an inner classes and get called in a button.
code:
ClientThread
private class ChatClientThread extends Thread {
#Override
public void run() {
Socket socket = null;
DataOutputStream dataOutputStream = null;
try {
socket = new Socket("192.168.0.113", 23);
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
dataOutputStream.writeUTF(" "+"SolveProblemOrder_2");
dataOutputStream.flush();
ServerThread serv =new ServerThread();
serv.start();
} catch (UnknownHostException e) {
e.printStackTrace();
final String eString = e.toString();
TicketDetails.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(TicketDetails.this, eString, Toast.LENGTH_LONG).show();
}
});
} catch (IOException e) {
e.printStackTrace();
final String eString = e.toString();
TicketDetails.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(TicketDetails.this, eString, Toast.LENGTH_LONG).show();
}
});
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
TicketDetails.this.runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
}
}
ServerThread
public class ServerThread extends Thread {
private ServerSocket serverSocket;
private Socket clientSocket;
public void run(){
try{
// Open a server socket listening on port 23
InetAddress addr = InetAddress.getByName(getLocalIpAddress());
serverSocket = new ServerSocket(23, 0,addr);
try{
clientSocket = serverSocket.accept();
DataInputStream dataInputStream = new DataInputStream(clientSocket.getInputStream());
String newMsg = null;
Toast.makeText(getApplicationContext(), newMsg, Toast.LENGTH_LONG).show();
// Client established connection.
// Create input and output streams
while (true) {
if (dataInputStream.available() > 0) {
newMsg = dataInputStream.readUTF();
}
}}catch(Exception e){
e.printStackTrace();
}
// Perform cleanup
} catch(Exception e) {
// Omitting exception handling for clarity
}
}
private String getLocalIpAddress() throws Exception {
String resultIpv6 = "";
String resultIpv4 = "";
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()){
if (inetAddress instanceof Inet4Address) {
resultIpv4 = inetAddress.getHostAddress().toString();
} else if (inetAddress instanceof Inet6Address) {
resultIpv6 = inetAddress.getHostAddress().toString();
}
}
}
}
return ((resultIpv4.length() > 0) ? resultIpv4 : resultIpv6);
}
}
i start those two threads in a button Click listener:
ChatClientThread chatClient=new ChatClientThread();
chatClient.start();
ServerThread serv =new ServerThread();
serv.start();
if this won't work using server/client in the same activity using the same port is there any other way to listen to a socket like is there a built in listener or something like that.
any help is appreciated
You write to socket thru socket.getOutputStream() and you must read from InputStream of socket.getInputStream() ;
You can adapt your code .
Your server use InputStream from socket to read data ,so you must to do also in your client code , cause you want also to receive data not only to send.
check this out just read is is very simple.
https://systembash.com/a-simple-java-tcp-server-and-tcp-client/
See the code for reading from socket taht start with :
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
and code for writing to socket:
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
or search google : java client server .
The ideea is that you send data to the socket outputstream and you can read it from same socket inputstream.
you see here example it read data from socket input and send data thru socket output , to server
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
clientSocket.close();
Related
Can somebody explain to me what I am doing wrong.First time I try to implement TCP between Java and C#:
Sever code c#
`
public void CreateServer()
{
Thread thread = new Thread(() =>
{
IPAddress addr = IPAddress.Parse(localIP);
tcpListener = new TcpListener(addr, 5053);
if (tcpListener != null)
{
tcpListener.Start();
while (!end)
{
TcpClient tcpClient = tcpListener.AcceptTcpClient();
var ip = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString();
Console.WriteLine("Client connected from "+ip);
NetworkStream clientStream = tcpClient.GetStream();
StreamReader reader = new StreamReader(clientStream, Encoding.UTF8);
try
{
string request = reader.ReadToEnd();
Console.WriteLine("Message from client: " + request);
Byte[] StringToSend = Encoding.UTF8.GetBytes("Server");
clientStream.Write(StringToSend, 0, StringToSend.Length);
Console.WriteLine("Sending response back");
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
});
thread.Start();
}
`
Client code java
`
public class TCP {
private String IP;
private InetAddress server;
private Socket socket;
public TCP(String IP) {
this.IP = IP;
}
protected void runTCP() {
try {
server = InetAddress.getByName(IP);
socket = new Socket(server, 5053);
System.out.println("Client connected. Listening on port 5053");
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendMessage(String message) {
try {
System.out.println("Sending data...");
if (socket.isClosed()) socket = new Socket(server, 5053);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.print(message);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void getResponseServer() {
Thread thread = new Thread() {
#Override
public void run() {
try {
System.out.println("Attempting to get response...");
if (socket.isClosed()) socket = new Socket(server, 5053);
BufferedReader mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String mServerMessage = mBufferIn.readLine();
System.out.println("Server message: " + mServerMessage);
} catch (Exception e) {e.printStackTrace();}
}
};
thread.start();
}
}
`
Output on server I get when sending "Hello" from client to server:
Client connected from 192.16.... Message from client: Hello Sending response back Client connected from 192.16....
Output on client:
Client connected. Listening on port 5053 Sending data... Attempting to get response...
Never gets response... Why?
Tried researching but found nothing yet, tried other code but didnt work aswell...
sorry , I can't comment. maybe you can use telnet command to vertify c# code is corrent.
telnet ip port
first, locate problem, then solve it.
if server is ok , we can use nc command vertify client code, I have test your java code , except every send data will close socket , other is ok.
Fixed it by removing writer.close() cause that causes socket closing and makes another connection to the server by creating again the socket which makes the server wait for a stream of data and the client wait for a response...
System.out.println("Sending data...");
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
writer.println(message);
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
So i'm trying to send multiple lines of code everytime i type something in the client console. However when doing this it only prints the output of the client in the server once, what i would like to do is print the clients output in the server everytime after entering a line.
Client:
try {
Scanner scanner = new Scanner(System.in);
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
DataOutputStream outputStream;
System.out.println("Write something to client:");
while(scanner.hasNext()) {
System.out.println("Write something to client:");
outputStream = new DataOutputStream(socket.getOutputStream());
String message = scanner.nextLine();
outputStream.writeUTF(message);
}
} catch (IOException e) {
System.out.println("[ERROR] Unable to get streams from server");
}
}
ClientThread:
#Override
public void run() {
try {
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
System.out.println(inputStream.readUTF());
} catch (IOException e) {
e.printStackTrace();
}
}
Server:
public Server() {
try {
serverSocket = new ServerSocket(port);
System.out.println("[SERVER] Server initialized successfully");
// consider using!
Runtime.getRuntime().addShutdownHook(new Thread());
} catch (IOException e) {
System.out.println("[ERROR] Unable to launch server on port " + port);
}
while (true) {
Socket socket = null;
try {
socket = serverSocket.accept();
} catch (IOException e) {
System.out.println("[ERROR] Unable to accept client request");
}
System.out.println("[SERVER] New user joined the chat: " + socket);
groupCounter++;
ClientThread client = new ClientThread("Client " + groupCounter, socket);
Thread thread = new Thread(client);
thread.start();
groupClients.add(client);
//System.out.println(groupCounter);
}
The problem is in the server side, serverSocket.accept() stops the execution and waits for a client to connect to the server socket. That's why you only receive one message every time.
Add an infinite loop in the ClientThread to make sure it keeps on reading the client socket input.
try {
while (true) {
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
System.out.println(inputStream.readUTF());
}
} catch (IOException e) {
e.printStackTrace();
}
The program is intended to have multiple clients connect to a single server and the clients are able to send and receive messages among other clients.
For example if Client A says "Hi", Client B and Client C connected to the server would also receive "Hi".
In my current code, the server only receives the messages sent by the clients.
I'm currently looking for a solution to have the server broadcast the message sent by a client (eg. ClientA) to other clients. Any advice would be much appreciated.
This server class handles the connections of multiple clients with the use of threads:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
class EchoThread extends Thread {
private Socket socket;
//constructor
public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
}
#Override
public void run() {
DataInputStream inp = null;
try {
inp = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
//print whatever client is saying as long as it is not "Over"
String line = "";
while (!line.equals("Over")) {
try {
line = inp.readUTF();
System.out.println(line);
} catch (IOException e) { System.out.println(e); }
}
//closes connection when client terminates the connection
System.out.print("Closing Connection");
socket.close();
} catch (IOException e) { System.out.println(e); }
}
}
public class Server {
private static final int PORT = 5000;
public static void main(String args[]) {
ServerSocket serverSocket = null;
Socket socket = null;
//starts the server
try {
serverSocket = new ServerSocket(PORT);
System.out.println("Server started");
System.out.println("Waiting for a client ...\n");
} catch (IOException e) { System.out.println(e); }
//while loop to accept multiple clients
int count = 1;
while(true) {
try {
socket = serverSocket.accept();
System.out.println("Client " + count + " accepted!");
count++;
} catch (IOException e) { System.out.println(e); }
//starts the server thread
new EchoThread(socket).start();
}
}
}
and this is the client class (I have multiple instances of this code running):
import java.net.*;
import java.io.*;
public class ClientA {
private Socket socket = null;
private DataInputStream input = null;
private DataOutputStream output = null;
public ClientA(String address, int port) {
//establish connection
try {
socket = new Socket(address, port);
System.out.println("Connected");
//takes input from terminal
input = new DataInputStream(System.in);
//sends output to the socket
output = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) { System.out.println(e); }
//string to read message from input
String line = "";
//keep reading until "Over" is input
while (!line.equals("Over")) {
try {
line = input.readLine();
output.writeUTF(line);
} catch (IOException e) { System.out.println(e); }
}
//close the connection
try {
input.close();
output.close();
socket.close();
} catch (IOException e) { System.out.println(e); }
}
public static void main (String args[]) {
ClientA client = new ClientA("127.0.0.1", 5000);
}
}
Do feel free to correct me on my code comments as I'm still not very familiar with socket programming.
You did well. Just add a thread to receive message in ClientA; and store socket clients in Server.
In fact, Server is also a "client" when is send message to client.
I add some code based on your code. It works well, hope it's helpful.
class EchoThread extends Thread {
//*****What I add begin.
private static List<Socket> socketList = new ArrayList<>();
//*****What I add end.
private Socket socket;
//constructor
public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
socketList.add(socket);
}
#Override
public void run() {
DataInputStream inp = null;
try {
inp = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
//print whatever client is saying as long as it is not "Over"
String line = "";
while (!line.equals("Over")) {
try {
line = inp.readUTF();
System.out.println(line);
//*****What I add begin.
sendMessageToClients(line);
//*****What I add end.
} catch (IOException e) { System.out.println(e); break;}
}
//closes connection when client terminates the connection
System.out.print("Closing Connection");
socket.close();
} catch (IOException e) { System.out.println(e); }
}
//*****What I add begin.
private void sendMessageToClients(String line) throws IOException {
for (Socket other : socketList) {
if (other == socket) {
continue;//ignore the sender client.
}
DataOutputStream output = new DataOutputStream(other.getOutputStream());
output.writeUTF(line);
}
}
//*****What I add end.
}
public class ClientA {
private Socket socket = null;
private DataInputStream input = null;
private DataOutputStream output = null;
public ClientA(String address, int port) {
//establish connection
try {
socket = new Socket(address, port);
System.out.println("Connected");
//takes input from terminal
input = new DataInputStream(System.in);
//sends output to the socket
output = new DataOutputStream(socket.getOutputStream());
//*****What I add begin.
//Here create a thread to receive message from server.
DataInputStream inp = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
new Thread(() -> {
while (true) {
String str;
try {
str = inp.readUTF();
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();//error.
break;
}
}
}, "Client Reveiver.").start();
//*****What I add end.
} catch (IOException e) { System.out.println(e); }
//string to read message from input
String line = "";
//keep reading until "Over" is input
while (!line.equals("Over")) {
try {
line = input.readLine();
output.writeUTF(line);
} catch (IOException e) { System.out.println(e); }
}
//close the connection
try {
input.close();
output.close();
socket.close();
} catch (IOException e) { System.out.println(e); }
}
I would have a single server thread which would maintain a register of the clients, possibly in a concurrent collection. Then I would send each message received from a client to all other clients.
I tried to write a simple program that runs a server and then accepts two clients. Then one of them tries to send a string to another client.
but my code doesn't work and I don't know why.
This is my TestClient class:
public class TestClient extends Thread{
int id;
String Name;
Socket client;
boolean isAsk;
public TestClient(int id,String clientName,boolean isAsk) throws IOException {
this.id=id;
this.Name=clientName;
this.isAsk=isAsk;
}
public void connectTheClientToTheLocalHost(ServerSocket server){
try {
client = new Socket("localhost",1111);
server.accept();
} catch (IOException e) {
e.printStackTrace();
}
}
public void readFromTerminal(){
try {
InputStream is=client.getInputStream();
OutputStream os = client.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.println("sdklfsdklfk");
pw.flush();
pw.close();
}catch (IOException e){
e.printStackTrace();
}
}
public void closeTheCientSocket(){
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void write(){
try {
Scanner sc = new Scanner(client.getInputStream());
BufferedWriter bw = new BufferedWriter(new FileWriter(new File("file1.txt")));
String st =sc.nextLine();
bw.write(st);
bw.close();
}catch (IOException e){
e.printStackTrace();
}
}
#Override
public void run() {
if(isAsk){
readFromTerminal();
}
else{
write();
}
}
and this is the main function:
public class PCServer {
public static void main(String[] args){
try {
ServerSocket s = new ServerSocket(1111);
TestClient t1=(new TestClient(1,"reza",true));
TestClient t2=(new TestClient(2,"man",false));
t1.connectTheClientToTheLocalHost(s);
t1.start();
Scanner sc = new Scanner(t1.client.getInputStream());
String st=sc.nextLine();
System.out.println(st);
t1.closeTheCientSocket();
t2.connectTheClientToTheLocalHost(s);
PrintWriter pw = new PrintWriter(t2.client.getOutputStream());
pw.println(st);
pw.flush();
t2.start();
t2.closeTheCientSocket();
}catch (Exception e){
e.printStackTrace();
}
}
}
actually this code returns an exception in
String st=sc.nextLine();
in main function and says that there is no line found.
what is the problem?
ServerSocket in java usually used in another way.
If you need point-to-point connection, one host creates a ServerSocket and accepts connections. Examples:
First host example:
try(ServerSocket serverSocket = new ServerSocket(5555);
Socket socket = serverSocket.accept();
// it more convenient to use DataInputStream instead of Scanner I think
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());) {
while (!Thread.currentThread().isInterrupted()) {
String msg = dataInputStream.readUTF();
System.out.println("got request: " + msg);
dataOutputStream.writeUTF("1-response");
dataOutputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
Second host example:
try(Socket socket = new Socket("127.0.0.1", 5555);
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream())) {
while (!Thread.currentThread().isInterrupted()) {
dataOutputStream.writeUTF("2-request");
dataOutputStream.flush();
String msg = dataInputStream.readUTF();
System.out.println("got response: " + msg);
}
} catch (IOException e) {
e.printStackTrace();
}
If you want one host talk to another over the server (broker), then you need plane java Sockets on hosts and ServerSocket on broker, and broker must transmit messages it received from one host to another. Examples:
Broker (run it in separate thread or process)
try {
List<Socket> sockets = new ArrayList<>();
ServerSocket serverSocket = new ServerSocket(5555);
// accepting connections from 2 clients
for (int i = 0; i < 2; i++) {
Socket socket = serverSocket.accept();
sockets.add(socket);
}
// streams for first host
InputStream hostOneInputStream = sockets.get(0).getInputStream();
DataInputStream hostOneDataInputStream = new DataInputStream(sockets.get(0).getInputStream());
DataOutputStream hostOneDataOutputStream = new DataOutputStream(sockets.get(0).getOutputStream());
// streams for second host
InputStream hostTwoInputStream = sockets.get(1).getInputStream();
DataInputStream hostTwoDataInputStream = new DataInputStream(sockets.get(1).getInputStream());
DataOutputStream hostTwoDataOutputStream = new DataOutputStream(sockets.get(1).getOutputStream());
while (!Thread.currentThread().isInterrupted()) {
if (hostOneInputStream.available() > 0) {
String msg = hostOneDataInputStream.readUTF();
System.out.println("got message from host 1: " + msg);
hostTwoDataOutputStream.writeUTF(msg);
hostTwoDataOutputStream.flush();
System.out.println("message " + msg + " sent to host two");
}
if (hostTwoInputStream.available() > 0) {
String msg = hostTwoDataInputStream.readUTF();
System.out.println("got message from host 2: " + msg);
hostOneDataOutputStream.writeUTF(msg);
hostOneDataOutputStream.flush();
System.out.println("message " + msg + " sent to host one");
}
}
} catch (IOException e) {
e.printStackTrace();
}
First host (run it in separate thread or process)
try(Socket socket = new Socket("127.0.0.1", 5555);
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream())) {
while (!Thread.currentThread().isInterrupted()) {
dataOutputStream.writeUTF("1");
dataOutputStream.flush();
String msg = dataInputStream.readUTF();
System.out.println("got msg: " + msg);
TimeUnit.SECONDS.sleep(5);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
Second host (run it in separate thread or process)
try(Socket socket = new Socket("127.0.0.1", 5555);
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream())) {
while (!Thread.currentThread().isInterrupted()) {
String msg = dataInputStream.readUTF();
System.out.println("got msg: " + msg);
TimeUnit.SECONDS.sleep(5);
dataOutputStream.writeUTF("2");
dataOutputStream.flush();
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
I have two Java applications, where an Android client connects to a server on a computer and sends a message using BufferedWriter over websockets.
The client:
try {
toast("Sending...");
Socket sock = new Socket(ip, PORT);
OutputStream os = sock.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
bw.flush();
bw.write("Hello Server!");
toast("Connected!");
} catch (UnknownHostException e) {
toast(e.getMessage());
} catch (IOException e) {
toast(e.getMessage());
}
The server:
public static void main(String[] args) {
ServerSocket server;
ConnectionThread ct;
Socket s;
ExecutorService es = Executors.newSingleThreadExecutor();
try {
System.out.println("Starting server...");
server = new ServerSocket(1337);
s = server.accept();
ct = new ConnectionThread(s);
es.execute(ct);
} catch (IOException ex) {
ex.printStackTrace();
}
}
The ConnectionThread class:
public class ConnectionThread implements Runnable {
private Socket sock;
private InputStream is;
private BufferedReader br;
private boolean online;
public ConnectionThread(Socket s) {
System.out.println("Creating connection thread.");
this.sock = s;
online = true;
}
#Override
public void run() {
String input = "";
try {
System.out.println("Starting to read...");
is = sock.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
while (online) {
input = br.readLine();
if(input != null){
System.out.print("Received message: ");
System.out.println(input);
}
}
br.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
When I run the server, and then the client, the client will show the "Connected!" toast, and the server's output will be:
Starting server...
Creating connection thread.
Starting to read...
So, it seems like the connection is actually being made, but the message does not arrive. Does anybody know why this could be happening?
Your server is expecting a complete line terminated by a newline. Try:
bw.write("Hello Server!");
bw.newLine();
Do it like this...
String s = new String();
while ((br.readLine())!=null) {
s = s+br.readLine();
System.out.print("Received message: ");
System.out.println(input);
}
}
And
bw.println("Hello Server");
I notice that you don't send an endline on your client, so the BufferedReader.readline() will never return, because it cannot match the \n-character. Try it again with
bw.write("Hello Server!\n");
on the client side.