I got this training task on my school which says: Make a change in "SimpleClient" so that it makes a GET request to a address given on the command line and stores the content of the response to a file on disk.
import java.net.*;
import java.io.*;
public class SimpleClient {
public static void main(String[] args) {
try {
Socket con = new Socket(args[0], Integer.parseInt(args[1]));
PrintStream out = new PrintStream(con.getOutputStream());
out.print(args[2]);
out.write(0); // mark end of message
out.flush();
InputStreamReader in = new InputStreamReader(con.getInputStream());
int c;
while ((c = in.read())!=-1)
System.out.print((char)c);
con.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
As far as I can se the "con" instance of Socket should make a connection to a host (args[0] eg. www.google.com) through a port number (args[1]). Then a PrintStream "out" is made, but what is the function of out.print(args[2]) and out.write(0)? I do not understand the program completely so I would appreciate if someone could explain it to me and maybe tell what should be changed to make it work.
Opening a socket connection is not the same as firing a GET request. Have a look at Using java.net.URLConnection to fire and handle HTTP requests
Okay, I found a solution if anyone should be interested.
import java.net.*;
import java.io.*;
public class SimpleClient {
public static void main(String[] args) {
try {
FileWriter fw = new FileWriter(args[args.length - 1]);
BufferedWriter bw = new BufferedWriter(fw);
try {
Socket con = new Socket(args[0], Integer.parseInt(args[1]));
PrintStream out = new PrintStream(con.getOutputStream());
out.println("GET /search?q=" + args[2] + " HTTP/1.1");
out.println("Host: www.google.com");
out.println("");
out.write(0); // mark end of message
out.flush();
InputStreamReader in = new InputStreamReader(
con.getInputStream());
int c;
while ((c = in.read()) != -1)
bw.write((char) c);
con.close();
} catch (IOException e) {
System.err.println(e);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
Related
I want to send arraylist on multithreading server to client . So far i just write the conection and the clients can write and send to server msg ,the server just send back the msg to client is write somathing just sending. My main problems is how to transfer from server to client the arraylist ?
i am new on this and i dont know nothing for arralist .
code server :
import java.io.*;
import java.net.*;
import java.util.ArrayList;
// Server class
class Server {
public static void main(String[] args)
{
private ArrayList<Objects> Obj = new ArrayList<Objects>();
// file read
// String filePath = "Hotels_new.txt";
// System.out.println(Read_File( filePath ));
ServerSocket server = null;
try {
// server is listening on port 1234
server = new ServerSocket(1234);
server.setReuseAddress(true);
// running infinite loop for getting
// client request
while (true) {
// socket object to receive incoming client
// requests
Socket client = server.accept();
// Displaying that new client is connected
// to server
System.out.println("New client connected" + client.getInetAddress().getHostAddress());
// create a new thread object
ClientHandler clientSock = new ClientHandler(client);
// This thread will handle the client
// separately
new Thread(clientSock).start();
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (server != null) {
try {
server.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static String Read_File(String filePath)
{
// Declaring object of StringBuilder class
StringBuilder builder = new StringBuilder();
// try block to check for exceptions where
// object of BufferedReader class us created
// to read filepath
try (BufferedReader buffer = new BufferedReader(
new FileReader(filePath))) {
String str;
// Condition check via buffer.readLine() method
// holding true upto that the while loop runs
while ((str = buffer.readLine()) != null) {
builder.append(str).append("\n");
}
}
// Catch block to handle the exceptions
catch (IOException e) {
// Print the line number here exception occurred
// using printStackTrace() method
e.printStackTrace();
}
// Returning a string
return builder.toString();
}
// ClientHandler class
private static class ClientHandler implements Runnable {
private final Socket clientSocket;
// Constructor
public ClientHandler(Socket socket)
{
this.clientSocket = socket;
}
public void run()
{
PrintWriter out = null;
BufferedReader in = null;
try {
// get the outputstream of client
out = new PrintWriter( clientSocket.getOutputStream(), true);
// get the inputstream of client
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
// writing the received message from
// client
System.out.printf(" Sent from the client: %s\n",line);
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();
}
}
}
}
}
code client:
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.ArrayList;
// Client class
class Client {
// driver code
public static void main(String[] args)
{
// establish a connection by providing host and port
// number
try (Socket socket = new Socket("localhost", 1234)) {
// writing to server
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
// reading from server
BufferedReader in
= new BufferedReader(new InputStreamReader(
socket.getInputStream()));
// object of scanner class
Scanner sc = new Scanner(System.in);
String line = null;
while (!"exit".equalsIgnoreCase(line)) {
// reading from user
line = sc.nextLine();
// sending the user input to server
out.println(line);
out.flush();
// displaying server reply
System.out.println("Server replied "
+ in.readLine());
}
// closing the scanner object
sc.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
In order to send something more complex you will have to serialize it. You can choose how to do the serialization, maybe the easiest is to use ObjectOutputStream and ObjectInputStream on the server and client respectively. These can be used very similarly to the PrintWriter / BufferedReader solution you are doing now.
I had to change a few things as your example code did not compile.
Example server based on your code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
public class Server {
private static final List<Integer> myIntArray = List.of(1, 2, 3);
public static void main(String[] args) {
ServerSocket server = null;
try {
// server is listening on port 1234
server = new ServerSocket(1234);
server.setReuseAddress(true);
// running infinite loop for getting
// client request
while (true) {
// socket object to receive incoming client
// requests
Socket client = server.accept();
// Displaying that new client is connected
// to server
System.out.println("New client connected" + client.getInetAddress().getHostAddress());
// create a new thread object
ClientHandler clientSock = new ClientHandler(client);
// This thread will handle the client
// separately
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;
// Constructor
public ClientHandler(Socket socket) {
this.clientSocket = socket;
}
public void run() {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(clientSocket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
while (in.readLine() != null) {
objectOutputStream.writeObject(myIntArray);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Example client:
import java.io.*;
import java.net.*;
import java.util.*;
// Client class
class Client {
// driver code
public static void main(String[] args) {
// establish a connection by providing host and port
// number
try (Socket socket = new Socket("localhost", 1234);
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
// object of scanner class
Scanner sc = new Scanner(System.in);
String line = null;
while (!"exit".equalsIgnoreCase(line)) {
// reading from user
line = sc.nextLine();
// sending the user input to server
out.println(line);
out.flush();
// displaying server reply
List<Integer> integers = (List<Integer>) ois.readObject();
System.out.println("server: " + integers.get(0));
}
// closing the scanner object
sc.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Keep in mind that if you are about to send your own custom types, both sides will have to know about those to be able to serialize/deserialize. Also, your classes will have to be serializable.
I had stumbled upon a dead block when doing my assignment. It's a simple server and client program.
The details of this program is as follows;
Create a server class EncryptServer that listens for incoming connections. If there is a connection, accept it and create a thread EncryptServerSession to handle the input and output stream.
Create a thread class EncryptServerSession that takes in the input and output stream from the server class and process it.
Create a client class EncryptClient that connects to the server class and takes output stream from EncryptServerSession through EncryptServer.
Somehow the while true loop of the EncryptClient class is not working. I cannot seem to get into the loop. Is something wrong with my code? Thanks in advance.
EncryptServer
import java.net.*;
import java.io.*;
public class EncryptServer
{
public EncryptServer() throws IOException
{
ServerSocket serverSocket = new ServerSocket(1122);
System.out.println("Server started.");
while (true)
{
Socket conSocket = serverSocket.accept();
System.out.println("Client connected from " +
conSocket.getLocalAddress().getHostName());
Thread session = new
EncryptServerSession(conSocket.getInputStream(),
conSocket.getOutputStream());
session.start();
}
}
public static void main(String[] args)
{
try
{
EncryptServer server = new EncryptServer();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
EncryptServerSession
import java.net.*;
import java.io.*;
public class EncryptServerSession extends Thread
{
BufferedReader in;
Writer out;
public EncryptServerSession(InputStream inStream, OutputStream outStream)
{
Reader read = new InputStreamReader(inStream);
in = new BufferedReader(read);
out = new OutputStreamWriter(outStream);
}
public void strEncrypt()
{
try
{
String message = in.readLine();
out.write(message);
out.flush();
}
catch (Exception e)
{
}
}
public void run()
{
try
{
//System.out.println(in.readLine());
out.write("Please enter the message to be encrypted: ");
out.flush();
//strEncrypt();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
EncryptClient
import java.net.*;
import java.io.*;
public class EncryptClient
{
BufferedReader input, userTerm;
Writer output;
String line;
public EncryptClient() throws IOException
{
Socket clientSocket = new Socket("localhost", 1122);
Reader read = new InputStreamReader(clientSocket.getInputStream());
input = new BufferedReader(read);
userTerm = new BufferedReader(new InputStreamReader(System.in));
output = new OutputStreamWriter(clientSocket.getOutputStream());
/////////////// Somehow I cannot get into this loop, why? //////////
while (true)
{
System.out.println("test ");
System.out.println(input.readLine());
System.out.println("Enter message to be encrypted: ");
output.write(userTerm.readLine());
output.flush();
}
/////////////// Somehow I cannot get into this loop, why? //////////
}
public static void main(String[] args)
{
try
{
EncryptClient client = new EncryptClient();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
As I understand, you are trying to send a message to a server, do some logic, then send it back to the client. The above code seems to run well on my side. Here's what I've done:
run EncryptServer first. I expect this is the issue you are facing. or maybe your firewall isn't letting you listen on sockets.
in EncryptServerSession, You are reading lines but you aren't writing lines. either close the stream or write a new line after you finish.
...
out.write(message);
out.write("\r\n"); // write new line
out.flush();
...
} finally {
try {
out.close();
} catch (IOException e) {
}
}
OR
...
out.write(message);
out.write("\r\n"); // write new line
out.flush();
...
I was working on multi-client sockets and its working just fine, however it came to my mind on how to make the communication public by making the entered string being streamed to all clients.
e.g if there are lets say 3 clients A,B and C and client A sends "foo" to server, I want the server to stream "foo" to clients B and C as well.
The Server Module :
package multiclient;
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 Server {
public static void main(String args[]) {
Socket s = null;
ServerSocket ss2 = null;
System.out.println("Server Listening......");
try {
ss2 = new ServerSocket(4445); // can also use static final PORT_NUM , when defined
} catch (IOException e) {
e.printStackTrace();
System.out.println("Server error");
}
while (true) {
try {
s = ss2.accept();
System.out.println("connection Established");
ServerThread st = new ServerThread(s);
st.start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Connection Error");
}
}
}
}
class ServerThread extends Thread {
String line = null;
BufferedReader is = null;
PrintWriter os = null;
Socket s = null;
public ServerThread(Socket s) {
this.s = s;
}
public void run() {
try {
is = new BufferedReader(new InputStreamReader(s.getInputStream()));
os = new PrintWriter(s.getOutputStream());
} catch (IOException e) {
System.out.println("IO error in server thread");
}
try {
line = is.readLine();
while (line.compareTo("QUIT") != 0) {
os.println(line);
os.flush();
System.out.println("Response to Client : " + line);
line = is.readLine();
}
} catch (IOException e) {
line = this.getName(); //reused String line for getting thread name
System.out.println("IO Error/ Client " + line + " terminated abruptly");
} catch (NullPointerException e) {
line = this.getName(); //reused String line for getting thread name
System.out.println("Client " + line + " Closed");
} finally {
try {
System.out.println("Connection Closing..");
if (is != null) {
is.close();
System.out.println(" Socket Input Stream Closed");
}
if (os != null) {
os.close();
System.out.println("Socket Out Closed");
}
if (s != null) {
s.close();
System.out.println("Socket Closed");
}
} catch (IOException ie) {
System.out.println("Socket Close Error");
}
}//end finally
}
}
The Client Module:
package multiclient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
public static void main(String args[]) throws IOException{
InetAddress address=InetAddress.getLocalHost();
Socket s1=null;
String line=null;
BufferedReader br=null;
BufferedReader is=null;
PrintWriter os=null;
try {
s1=new Socket(address, 4445); // You can use static final constant PORT_NUM
br= new BufferedReader(new InputStreamReader(System.in));
is=new BufferedReader(new InputStreamReader(s1.getInputStream()));
os= new PrintWriter(s1.getOutputStream());
}
catch (IOException e){
e.printStackTrace();
System.err.print("IO Exception");
}
System.out.println("Client Address : "+address);
System.out.println("Enter Data to echo Server ( Enter QUIT to end):");
String response=null;
try{
line=br.readLine();
while(line.compareTo("QUIT")!=0){
os.println(line);
os.flush();
response=is.readLine();
System.out.println("Server Response : "+response);
line=br.readLine();
}
}
catch(IOException e){
e.printStackTrace();
System.out.println("Socket read Error");
}
finally{
is.close();os.close();br.close();s1.close();
System.out.println("Connection Closed");
}
}
}
The server can keep a collection of all client sockets (until one is closed). When a client message arrives, server writes it to all client sockets.
There's a problem though, socket.write() is blocking, so if we do it in a loop, a slow client will block the rest of the clients. You can spawn a new thread to write to each individual socket, if there aren't too many clients.
In the blocking IO world, to implement a true full-duplex protocol, it is necessary for server to have two threads per client, one for read, one for write.
You may also try NIO if you are brave enough...
There are many examples. Search for chat server. One good one if you don't mind using a framework is Netty, check the SecureChat example for working code. It is a short and focused example.
Edit: the link takes you to the example code.
I suggest:
1. Keep the threads you create in an ArrayList
2. Create a method in Server called writeString and a lock
private final Lock mutex = new ReentrantLock(true);
private ArrayList<ServerThread> list = new ArrayList<ServerThread>();
public void writeString(ServerThread t,String s)
{
mutex.lock();
for(ServerThread th:list)
if(th!=null && th!=t) //different from the thread receiving the string
th.writeString(s); //send string to other threads
mutex.unlock();
}
3. in ServerThread class, implement writeString method and add a Lock
private final Lock mutex = new ReentrantLock(true);
public void writeString(String s)
{
mutex.lock();
os.println(s);
os.flush();
mutex.unlock();
}
4. Keep a reference to the main Server thread by modifying the constructor
//in ServerThread
private Server parent=null;
SeverThread(Socket s, Server parent)
{
this.parent=parent;
/*the rest of the code*/
}
//in Server
ServerThread st = new ServerThread(s,this);
st.start();
list.add(st);
When you read the string in ServerThread, call the Server writeString method in order to notify all the clients
parent.writeString(this,s); //calls the method we created at 2.
I am beginner to java and learning Socket Programming.I am using the basic chat server socket communication. I am having difficulty to print the server and client messages to the console window.
I would also implement this concept when i design my chat Server window UI and will update the char server intercommunication messages to my UI. I would like to know as how can I achieve that ?
Code for 1
Server.java
package ChApp;
import java.io.IOException;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception {
Socket s;
ServerSocket server = new ServerSocket(3900);
while(true)
{
s = server.accept();
ServerHandl handle1 = new ServerHandl(s);
Thread t1= new Thread(handle1);
t1.start();
System.out.println("Connection Succesful...");
server.close();
}
}
}
Serverhandl.java
package ChApp;
import java.io.*;
import java.net.*;
public class ServerHandl implements Runnable {
Socket s= null;
BufferedReader read;
PrintWriter write;
String msg="Server is sending a sample msg";
public ServerHandl(Socket s)
{
this.s = s;
}
public void run()
{
try {
write = new PrintWriter(s.getOutputStream());
write.println(msg);
read = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(read.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
read.close();
write.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Client.java
package ChApp;
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException {
Socket s= null;
BufferedReader read;
PrintWriter write = null;
String h;
StringBuilder sb = new StringBuilder();
String sendmsg="Reply from client";
s= new Socket("localhost",3900);
read = new BufferedReader(new InputStreamReader(s.getInputStream()));
while((h=read.readLine())!=null)
{
sb.append(h);
}
write = new PrintWriter(s.getOutputStream(),true);
write.write(sendmsg);
write.flush();
s.close();
read.close();
write.close();
}
}
Your client is calling readLine() until it returns null, but your server is reading from the connection so it hasn't closed it yet, so the null will never arrive, so you're deadlocked.
Read one line from the server and then send a response, then close the socket. Have the server close the socket after it calls readLine().
I am running a client on android emulator and server (java) on the same PC and am using socket programming. Attaching code below. Individually both are running fine but the actual data transfer is not happening and am not able to figure it out.
Server side(PC):
import java.net.*;
import java.io.*;
public class Server_tcp {
void run(){
{
try {
System.out.println("In 1st try blck");
try {
System.out.println("In 2nd try blck");
Boolean end = false;
ServerSocket ss = new ServerSocket(4444);
System.out.println("socket created");
while(!end){
//Server is waiting for client here, if needed
Socket s = ss.accept();
System.out.println("socket accepted");
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter output = new PrintWriter(s.getOutputStream(),true); //Autoflush
String st = input.readLine();
System.out.println("Tcp Example" + "From client: "+st);
output.println("Good bye and thanks for all the fish :)");
s.close();
if (st==null){ end = true; }
}
ss.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException exp) {
// TODO Auto-generated catch block
exp.printStackTrace();
}
}
}
public static void main(String args[])
{
Server_tcp server = new Server_tcp();
while(true){
server.run();
}
}
}
Client Side (Android ):
package com.try3;
import android.app.Activity;
import android.os.Bundle;
import android.widget.EditText;
import java.io.*;
import java.net.*;
public class ClientTCPActivity extends Activity {
/** Called when the activity is first created. */
private EditText et;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.out.println("Before try net");
trynet();
System.out.println("after try net");
}
public void trynet() {
System.out.println("inside try net");
try {
System.out.println("inside try");
Socket s = new Socket("127.0.0.1",4444);
//outgoing stream redirect to socket
OutputStream out = (OutputStream) et.getContentDescription();
PrintWriter output = new PrintWriter(out);
output.println("Hello Android!");
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
//read line(s)
String st = input.readLine();
System.out.println(st);
//Close connection
s.close();
System.out.println(" try ");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
From the Android Emulator you should be referring to your PC using 10.0.2.2 instead of 127.0.0.1
I didn't understand what you are trying to do here.
OutputStream out = (OutputStream) et.getContentDescription();
PrintWriter output = new PrintWriter(out);
Did you mean something like:
PrintWriter output = new PrintWriter(s.getOutputStream(),true);
??