I've created a TCP Server in Java and a TCP client in Ruby. The problem is I'm not able to send more than 1 message in the same connection, Only the first message is sent while the other one is not sent.
here is the Java code
package com.roun512.tcpserver;
import java.io.*;
import java.net.*;
public class Program {
/**
* #param args
*/
public static void main(String[] args) throws Exception {
String clientSentence;
String capitalizedSentence;
ServerSocket Socket = new ServerSocket(6789);
while(true)
{
Socket connection = Socket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connection.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connection.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println(clientSentence);
capitalizedSentence = clientSentence + '\n';
outToClient.writeBytes(capitalizedSentence);
System.out.println("Sent msg");
}
}
}
And here is the client code
Client.rb
require 'socket'
class Client
def initialize()
server = TCPSocket.open("127.0.0.1", 6789)
if server.nil?
puts "error"
else
puts "connected"
end
server.puts("Hello\r\n")
sleep 2
server.puts("There\r\n")
server.close
end
end
Client.new()
I'm only receiving Hello. I have tried many other ways but none worked.
So my question is how to send more than 1 message in a single connection, Any help would be appreciated :)
Thanks in advance!
Socket.accept() waits for new connection after reading the first line.
Try the following:
public static void main(String[] args) throws Exception {
String clientSentence;
String capitalizedSentence;
ServerSocket Socket = new ServerSocket(6789);
while (true)
{
Socket connection = Socket.accept();
while(true)
{
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connection.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connection.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println(clientSentence);
capitalizedSentence = clientSentence + '\n';
outToClient.writeBytes(capitalizedSentence);
System.out.println("Sent msg");
}
}
}
If it works, change while (true) to some meaningful condition and don`t fotget to close the connection after the work is done.
Related
I have made 2 classes, one is client.java and one is server.java. I am using socket to communicate between them. The server and client connects but don't send data and stays connected.
client.java:
public static void main(String[] args) throws Exception {
Socket s = new Socket("localhost", 42069);
System.out.println("Connected to the server!");
BufferedWriter out = new BufferedWriter
(new OutputStreamWriter(s.getOutputStream()));
BufferedReader in = new BufferedReader
(new InputStreamReader(s.getInputStream()));
out.write("hi from client");
System.out.println(in.readLine());
s.close();
}
server.java:
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(42069);
System.out.println("\nWaiting For Connection...");
Socket s = ss.accept();
System.out.println("\nConnected to the client!");
BufferedReader in = new BufferedReader
(new InputStreamReader(s.getInputStream()));
BufferedWriter out = new BufferedWriter
(newOutputStreamWriter(s.getOutputStream()));
System.out.println(in.readLine());
out.write("hi from server");
}
when both connect, they stay like this:
s.jaerverva
Waiting For Connection...
Connected to the client!
client.java
Connected to the server!
when i terminate the client, i get this error on the server:
Exception in thread "main" java.net.SocketException: Connection reset
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:323)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:270)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:313)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:177)
at java.base/java.io.BufferedReader.fill(BufferedReader.java:162)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:329)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:396)
at HTTP.server.main(server.java:14)
I've written both a TCP server and a TCP client application in eclipse. The Client gets user input in the form of a string then sends it to the server who capitalizes it and sends it back. They need to keep looping until the server has received a certain number of requests in which case it closes the connection between he sockets and stops. Unfortunately it only seems to loop once. I will provide a sample output of what I'm talking about after the code.
import java.io.*;
import java.net.*;
public class TCPServer {
public static void main(String argv[]) throws Exception {
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
int requests = 0;
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader (new InputStreamReader( connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream (connectionSocket.getOutputStream());
do {
clientSentence = inFromClient.readLine();
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
outToClient.flush();
requests++;
}
while(requests < 10);
outToClient.writeBytes("REQUEST LIMIT REACHED");
}
}
}
and the client
import java.io.*;
import java.net.*;
public class TCPClient {
public static void main(String argv[]) throws Exception {
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
//Creates socket, replace the hostnmae/ip address with the ipaddress of the computer running the server application.
Socket clientSocket = new Socket("10.69.88.130", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader (clientSocket.getInputStream()));
do {
System.out.print("TO SERVER: ");
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
outToServer.flush();
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
}
while (!modifiedSentence.equals("REQUEST LIMIT REACHED"));
System.out.println(modifiedSentence);
clientSocket.close();
}
}
and finally the output I'm getting
TO SERVER: testa
FROM SERVER: TESTA
TO SERVER: testb
(nothing else is displayed after this line)
Well your code is working (kind of). You get a successful run, then you restart your client without restarting the server. Your request-value does not reset to 0 and after restarting the client the first request your client does is number 10 for your server.
So why is that request comming through? Because you flush the string first and then check your counter.
I have modified your server a little bit. Maybe that is what you are looking for?
import java.io.*;
import java.net.*;
public class TCPServer {
public static void main(String argv[]) throws Exception {
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
int requests = 0;
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader (new InputStreamReader( connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream (connectionSocket.getOutputStream());
while (requests < 10) {
clientSentence = inFromClient.readLine();
capitalizedSentence = clientSentence.toUpperCase();
outToClient.writeBytes(capitalizedSentence + " Request: " + requests + '\n');
outToClient.flush();
requests++;
}
outToClient.writeBytes("REQUEST LIMIT REACHED");
requests = 0;
}
}
}
I am trying to make a java program for client-server communication
I need to initialize a server socket and a client socket.
The server socket will accept a connection from the client.
After the connection has been accepted, the input i give to the client will be submitted to the server which will tell the client if the communication was successfull or not.
This is my code :
import java.io.*;
import java.net.*;
public class ClientServer {
public static void main(Strings args[]) throws Exceptions{
/*initialize server socket*/
Socket client_socket = new Socket("localhost", 12345);
BufferedReader reader = new BufferedReader(new InputStreamReader(client_socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(client_socket.getOutputStream()));
String serverMsg = null;
while ((serverMsg = reader.readLine()) != null) {
System.out.println("Client: " + serverMsg);
ServerSocket server_socket;
server_socket=new ServerSocket(12345);
while (true) {
Socket mysocket=server_socket.accept();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(mysocket.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(mysocket.getInputStream()));
writer.write("prova\n");
System.out.printls("data sent");
}
}
}
but I need to get input from keyboard, not "from the code".
Thanks a lot.
I am trying to implement a simple client server program that will continuously exchange messages until client decides to stop. I found many tutorials on this topic, however I am struggling with implementing the loop correctly. The server processes the first request but does not process the others.
It is probably some silly mistake so please excuse me for asking such basic question - I am new to sockets. I would be glad for any help. I provide all the code (based on some example that I found):
Client:
public class Client {
public static void main(String argv[]) throws Exception {
talkWithServer();
}
private static void talkWithServer() throws UnknownHostException, IOException {
String sentence;
String serverResponse;
BufferedReader brClient = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 9000);
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader brServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while(true) {
sentence = brClient.readLine();
out.writeBytes(sentence + '\n');
serverResponse = brServer.readLine();
System.out.println(serverResponse);
if (serverResponse.contains("<BYE>")) {
break;
}
}
clientSocket.close();
}
}
Server:
public class Server {
public static void main(String args[]) throws Exception {
String clientSentence;
ServerSocket welcomeSocket = new ServerSocket(9000);
Protocol protocol = new Protocol();
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
String response = protocol.processInput(clientSentence);
outToClient.writeBytes(response + '\n');
}
}
}
Protocol:
public class Protocol {
public String processInput(String theInput) {
String theOutput = "> " + theInput;
return theOutput;
}
}
I simplified the example for sake of easier debugging. Thanks for any tips!
My guess is line "Socket connectionSocket = welcomeSocket.accept();"
If I remember right, this will try to accept new client everytime, and since you are connecting just one, it will wait on that line forever in second iteration.
I suggest you paste that line before the while loop.
Try below
Socket connectionSocket = welcomeSocket.accept();
while (true) {
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
String response = protocol.processInput(clientSentence);
outToClient.writeBytes(response + '\n');
outToClient.flush();
}
I hava a problem with my code. I make a server with Java which waits for connections. When a client connects, if we(the server) send the command "showinfo", the cliend send its IP address back to the server.
The problem is that it is a multi-threaded server and many clients connect. So, if, for example, 2 clients connect to the server we have to type 2 times showinfo and then the clients give us the information. How can I make the clients respond immediately with typing "showinfo" for each one and don't wait until I type showinfo for all the clients. It's a bit tiring to type 50 times showinfo if there are 50 clients before you can execute your command. Thank you in advance (i have tried some thread synchronization and some sleep() join() commands but I haven't reach a conclusion yet I hope you can help a bit.)
Here 's the server code
import java.io.*;
import java.net.*;
import java.security.*;
public class Server implements Runnable{
private Socket server;
private static String command,info,message;
BufferedReader infromclient =null;
InputStream infromclient2=null;
DataOutputStream outtoclient =null;
static BufferedReader infrommaster=null;
private static int port=6789;
Server( Socket server ){
try{
this.server=server;
infromclient =new BufferedReader(new InputStreamReader(server.getInputStream()));
outtoclient =new DataOutputStream(server.getOutputStream());
infrommaster=new BufferedReader(new InputStreamReader(System.in));
}catch( IOException e ){
System.out.println("Exception accessing socket streams: "+e);
}
}
// main()
// Listen for incoming connections and handle them
public static void main(String[] args) {
ThreadGroup clients = new ThreadGroup("clients");
System.out.print("Waiting for connections on port " + port + "...");
System.out.println("\nIn total there are:"+clients.activeCount()+" clients\n");
try{
ServerSocket server = new ServerSocket(port);
Socket nextsocket;
// waiting for connections
while(true){
nextsocket = server.accept();
Thread client= new Thread(clients,new Server(nextsocket),"client"+(clients.activeCount()+1));
System.out.println("Client connected");
System.out.println("There are "+clients.activeCount()+" clients connected");
client.start();
}
}catch (IOException ioe){
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
public void run (){
try{
command=infrommaster.readLine();
outtoclient.writeBytes(command+"\n");
// showinfo
if(command.equals("showinfo")){
info=infromclient.readLine();
System.out.println("\nClient information\n\n" +info+"\n");
}
server.close();
}catch (IOException ioe){
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
and here is the code for the client:
import java.io.*;
import java.net.*;
import java.lang.*;
public class Client{
public static void main(String args[]) throws Exception{
String command2;
String info;
Socket clientSocket=null;
Socket scket=null;
BufferedReader inFromUser=null;
DataOutputStream outToServer=null;
BufferedReader inFromServer=null;
BufferedWriter tosite=null;
try{
clientSocket = new Socket(InetAddress.getLocalHost().getHostName(), 6789);
inFromUser =new BufferedReader(new InputStreamReader(System.in));
outToServer =new DataOutputStream(clientSocket.getOutputStream());
inFromServer =new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}catch(UnknownHostException | IOException e ){
System.out.println("Problem "+e);
}
command2=inFromServer.readLine();
System.out.println("From Server:" +command2);
// showinfo
if (command2.equals("showinfo")){
try{
InetAddress myip=InetAddress.getLocalHost();
info =("IP: " +myip.getHostAddress()+"\n");
System.out.println("\nSome system information\n" + info);
outToServer.writeBytes(info);
}catch (Exception e){
System.out.println("Exception caught ="+e.getMessage());
}
}
outToServer.flush();
outToServer.close();
inFromUser.close();
inFromServer.close();
clientSocket.close();
}
}
** the command clientSocket = new Socket(InetAddress.getLocalHost().getHostName(), 6789); means that it tests my pc(my ip in port 6789) .
If one thread is blocking on the readline, the other should eventually get control. That's the whole point of multithreading. I think I know your problem. Move the code where you are reading the input command into the run() method of the server instead. Then you should be good. I think the problem is that your threads are starting after you are polling for input.
Move these lines from the Server constructor to Server's run() method:
infromclient =new BufferedReader(new InputStreamReader(server.getInputStream()));
outtoclient =new DataOutputStream(server.getOutputStream());
infrommaster=new BufferedReader(new InputStreamReader(System.in));