Have a task to create a basic http server. I've gotten to the point where it asks you to send text response back that should be displayed in your browser if you go to http://localhost:8080/ but I just get a page cannot be displayed error. I think it must be something to do with the format of the response I'm sending but i just can't get it. Any help would be much appreciated.
import java.net.*;
import java.io.*;
import java.util.*;
class HttpServer{
public static void main(String[] args){
try{
ServerSocket ss = new ServerSocket(8080);
while(true){
HttpServerSession sesh = new HttpServerSession(ss.accept());
sesh.start();
}
}catch(IOException e){
System.err.println("IOException");
}
}
}
class HttpServerSession extends Thread {
private Socket client;
public HttpServerSession(Socket client){
this.client = client;
}
private void println(BufferedOutputStream bos, String s) throws IOException {
String news = s + "\r\n";
byte[] array = news.getBytes();
for(int i = 0; i < array.length; i++){
bos.write(array[i]);
}
return;
}
public void run(){
try{
InetAddress clientIP = client.getInetAddress();
System.out.println("We just got a message! " + clientIP.getHostAddress());
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String request = reader.readLine();
System.out.println(request);
String[] parts = request.split(" ");
if(parts.length == 3){
BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream());
String filename = parts[1].substring(1);
if(parts[0].equals("GET")){
while(true){
String line = reader.readLine();
System.out.println(line);
if(line == null || line.equals("")){
break;
}
}
println(bos, "OK");
println(bos, "");
println(bos, "Hello World");
}
}
client.close();
}catch(Exception e){
System.err.println("Exception in thread");
}
}
}
Turns out I just had to flush the BufferedOutputStream
Related
There is a string called numberPart inside a thread class called ServerRecieve. The location where .start() is being called is inside of a different class called Server.
The 'numberPart' will eventually be used as a port for file transferring later on.
My question is: How do I access the numberPart variable inside of the class called Server?
Screenshot of code running (server on left window, client on the right):
server on left window, client on the right
In the left window of the screenshot (server) you can see the that the first port number of the right window's command line argument which is 4021 being sent via a text message, and the server successfully receives it with the message "File transfer port found: 4021". Unfortunately this variable is located inside a different class. I would like to know how to access that variable inside the class called Server.
ServerRecieve code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ServerRecieve extends Thread
{
Socket servSocket;
boolean m_bRunThread = true;
boolean ServerOn = true;
public ServerRecieve(Socket s)
{
super();
servSocket = s;
}
public void run()
{
while(true)
{
try
{
BufferedReader readFromClient = new BufferedReader(new InputStreamReader(servSocket.getInputStream()));
String fromClient = readFromClient.readLine();
String a = fromClient;
int i;
for(i = 0; i < a.length(); i++)
{
char c = a.charAt(i);
if( '0' <= c && c <= '9' )
{
break;
}
}
String alphaPart = a.substring(0, i);
String numberPart = a.substring(i);
System.out.println("Recieved from client: " + alphaPart +"\n");
System.out.println("File transfer port found: " + numberPart + "\n");
//String[] filePortNumber = null;
//filePortNumber[0] = numberPart;
// Server thing = new Server(filePortNumber);
if(fromClient.equals(null))
{
System.exit(0);
}
OutputOptions();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
}
}
}
void OutputOptions()
{
System.out.println("Enter an option ('m', 'f', 'x'): ");
System.out.println("(M)essage (send)");
System.out.println("(F)ile (request) ");
System.out.println("e(X)it ");
}
}
Server source:
import java.io.*;
import java.net.*;
import java.util.*;
import javax.imageio.IIOException;
public class Server
{
private String[] serverArgs;
public Socket socket;
public Socket fileSocket;
public boolean keepRunning = true;
public int ConnectOnce = 0;
public String option = "";
public boolean isConnected = false;
public String FILE_TO_SEND = "/Users/nanettegormley/Documents/workspace/assignment2/src/servers/cdm.jpg";
public Server(String[] args) throws IOException
{
// set the instance variable
this.serverArgs = args;
if(ConnectOnce == 0)
{
int port_number1 = Integer.valueOf(serverArgs[1]);
ServerSocket serverSocket = new ServerSocket(port_number1);
socket = serverSocket.accept();
ConnectOnce = 4;
isConnected = true;
}
}
public String[] serverRun2(String[] args) throws IOException
{
serverArgs = args;
serverArgs = Arrays.copyOf(args, args.length);
serverSend.start();
return serverArgs;
}
Thread serverSend = new Thread()
{
public void run()
{
OutputOptions();
while(isConnected)
{
try
{
ServerRecieve serverThread = new ServerRecieve(socket);
serverThread.start();
// input the message from standard input
BufferedReader input2= new BufferedReader(new InputStreamReader(System.in));
option = input2.readLine();
if(option.equals("m") || option.equals("M"))
{
StandardOutput();
}
if(option.equals("f") || option.equals("F"))
{
FileTransferSend();
}
if(option.equals("x") || option.equals("X"))
{
System.exit(0);
}
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
}
}
};
public void StandardOutput()
{
try
{
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
System.out.println("Enter your message: ");
// input the message from standard input
BufferedReader input2= new BufferedReader(new InputStreamReader(System.in));
String line = "";
line= input2.readLine();
newmessage += line + " ";
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
String sendMessage = newmessage;
bw.write(sendMessage + "\n");
bw.newLine();
bw.flush();
System.out.println("Message sent to client: "+sendMessage);
StandardInput();
//run();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
}
}
void FileTransferSend()
{
//connect to the filetransfer
try
{
System.out.println("Which file do you want? ");
Scanner scanner = new Scanner(System.in);
String filename = scanner.nextLine();
FileInputStream fis = new FileInputStream(new File(filename));
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(fileSocket.getOutputStream()));
int element;
while((element = fis.read()) !=1)
{
dos.write(element);
}
byte[] byteBuffer = new byte[1024]; // buffer
while(fis.read(byteBuffer)!= -1)
{
dos.write(byteBuffer);
}
OutputOptions();
// dos.close();
// fis.close();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
}
}
void OutputOptions()
{
System.out.println("Enter an option ('m', 'f', 'x'): ");
System.out.println("(M)essage (send)");
System.out.println("(F)ile (request) ");
System.out.println("e(X)it ");
}
public void StandardInput()
{
OutputOptions();
while(true)
{
try
{
// input the message from standard input
BufferedReader input2= new BufferedReader(new InputStreamReader(System.in));
String line2 = "";
option= input2.readLine();
if(option.equals("m") || option.equals("M"))
{
StandardOutput();
}
if(option.equals("f") || option.equals("F"))
{
FileTransferSend();
}
if(option.equals("x") || option.equals("X"))
{
System.exit(0);
}
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
finally
{
}
}
}
}
Full code with all files:
https://www.dropbox.com/s/0yq47gapsd3dgjp/folder33.zip?dl=0
My question is: What changes can I make to the code that would allow me to access numberPart while being inside Server?
EDIT: Is there a way to bump a question that hasn't gotten any answers or should I just delete this one and repost it somewhere?
I would think that you could use either a listener or callback pattern to solve this.
(I'm losing my Java memory now that I'm doing C# so please bear with me..)
interface PortAssignable {
public assignPort(int port);
}
Then have the Server class implement that interface
public Server implements PortAssignable {
...
}
And ServerReceive
// Constructor
public ServerRecieve(Socket s, PortAssignable portNotifyListener) {
_portNotifyListener = portNotifyListener;
... your other code ...
}
Make sure when you create an instance of ServerReceive, you pass in your Server instance, via this.
ServerRecieve serverThread = new ServerRecieve(socket, this);
Now, when you get your numberPart, your next line can be
_portNotifyListener.assignPort(numberPart);
How you choose to implement the assignPort method in your Server class is up to you.
P.S. I saw this question from /r/programming.
I'm trying to make a simple program with a server and client, passing text strings back and forth. I'm having trouble making the connection. I have a test printing line right below the socket accept line and it never prints, so I assume the problem is there, but I'm not sure how to do a more thorough check.
I have written this program in Eclipse if that makes a difference.
This is the server:
import java.io.*;
import java.net.*;
public class HW2Q1S {
public static void main(String[] args) throws Exception {
try {
//connection
ServerSocket srvr = new ServerSocket(7654);
Socket skt = srvr.accept();
System.out.println(skt.getPort());
//data xfer
BufferedReader sIn = new BufferedReader(new InputStreamReader(skt.getInputStream()));
PrintWriter sOut = new PrintWriter(skt.getOutputStream(), true);
//string receiving
int count = 1;
String msg = "";
while((msg = sIn.readLine()) != null) {
while(count < 11) {
msg = sIn.readLine();
System.out.println("Received: "+ msg);
String returnMsg = msg.toUpperCase();
System.out.println("Capped: "+ returnMsg);
sOut.write(returnMsg);
count++;
}
} //end of read from client in while loop
if (count == 10) {
System.out.println("Max reached.");
}
srvr.close();
return;
}
catch(Exception e) {
System.out.println("Error caught: " + e);
}
} // end of main
} // end of class
And this is the client:
import java.util.Random;
import java.io.*;
import java.net.*;
public class HW2Q1C {
public static void main(String[] args) throws IOException {
String capped = "";
String temp = "";
try {
//make the connection
Socket skt = new Socket("localhost", 7654);
BufferedReader cIn = new BufferedReader(new InputStreamReader(skt.getInputStream()));
PrintWriter cOut = new PrintWriter(skt.getOutputStream(), true);
//send 11 strings
for (int i = 0; i < 11; i++) {
temp = Stringer();
cOut.write(temp);
System.out.println("Sending: " + temp);
}
//receive server strings
while(cIn.readLine() != null) {
capped = cIn.readLine();
System.out.println("From server: "+ capped);
}
skt.close();
} // end of connection try block
catch(Exception e) {
System.out.print("Whoops! It didn't work!\n");
}
} //end of main
static String Stringer() {
String msg, alpha;
msg = "";
alpha = "abcdefghijklmnopqrstuvwxyz";
Random rnd = new Random();
for (int i = 0; i < 10; i++) {
msg += alpha.charAt(rnd.nextInt(25));
}
return msg;
}
} //end of class
Thanks!
I think I found your problem.
You should use println instead of write. I am quite sure the problem is that write does not send an actual line string + \n and therefore the server cannot read a line.
I modified your example a little bit to make it easier to test and understand, but this works for me:
Server:
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception {
try {
//connection
ServerSocket srvr = new ServerSocket(7654);
Socket skt = srvr.accept();
System.out.println(skt.getPort());
BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
String msg = "";
while ((msg = in.readLine()) != null) {
System.out.println("Received: " + msg);
} //end of read from client in while loop
srvr.close();
} catch (Exception e) {
System.out.println("Error caught: " + e);
}
} // end of main
} // end of class
Client:
import java.util.Random;
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws IOException {
try {
Socket socket = new Socket("localhost", 7654);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
for (int i = 0; i < 11; i++) {
out.println(Stringer()); //<-- println instead of write
}
socket.close();
} // end of connection try block
catch(Exception e) {
System.out.print(e.toString());
}
} //end of main
static String Stringer() {
String msg, alpha;
msg = "";
alpha = "abcdefghijklmnopqrstuvwxyz";
Random rnd = new Random();
for (int i = 0; i < 10; i++) {
msg += alpha.charAt(rnd.nextInt(25));
}
return msg;
}
} //end of class
ServerOutput:
Received: scnhnmaiqh
Received: tuussdmqqr
Received: kuofypeefy
Received: vghsinefdi
Received: ysomirnfit
Received: lbhqjfbdio
Received: qhcguladyg
Received: wihrogklfi
Received: tipikgfvsx
Received: fmpdcbtxqb
Received: yujtuefqft
I found a socket SMTP client example slightly modified for it to connect to gmail using SSLsockets, but now I don't know how to authorise account, that I am sending from. (I don't use JAVAMAIL, because this is homework)
public class SMTP {
public static void main(String args[]) throws IOException,
UnknownHostException {
String msgFile = "file.txt";
String from = "from#gmail.com";
String to = "to#gmail.com";
String mailHost = "smtp.gmail.com";
SMTP mail = new SMTP(mailHost);
if (mail != null) {
if (mail.send(new FileReader(msgFile), from, to)) {
System.out.println("Mail sent.");
} else {
System.out.println("Connect to SMTP server failed!");
}
}
System.out.println("Done.");
}
static class SMTP {
private final static int SMTP_PORT = 25;
InetAddress mailHost;
InetAddress localhost;
BufferedReader in;
PrintWriter out;
public SMTP(String host) throws UnknownHostException {
mailHost = InetAddress.getByName(host);
localhost = InetAddress.getLocalHost();
System.out.println("mailhost = " + mailHost);
System.out.println("localhost= " + localhost);
System.out.println("SMTP constructor done\n");
}
public boolean send(FileReader msgFileReader, String from, String to)
throws IOException {
SSLSocket smtpPipe;
InputStream inn;
OutputStream outt;
BufferedReader msg;
msg = new BufferedReader(msgFileReader);
smtpPipe = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(InetAddress.getByName("smtp.gmail.com"), 465);
if (smtpPipe == null) {
return false;
}
inn = smtpPipe.getInputStream();
outt = smtpPipe.getOutputStream();
in = new BufferedReader(new InputStreamReader(inn));
out = new PrintWriter(new OutputStreamWriter(outt), true);
if (inn == null || outt == null) {
System.out.println("Failed to open streams to socket.");
return false;
}
String initialID = in.readLine();
System.out.println(initialID);
System.out.println("HELO " + localhost.getHostName());
out.println("HELO " + localhost.getHostName());
String welcome = in.readLine();
System.out.println(welcome);
System.out.println("MAIL From:<" + from + ">");
out.println("MAIL From:<" + from + ">");
String senderOK = in.readLine();
System.out.println(senderOK);
System.out.println("RCPT TO:<" + to + ">");
out.println("RCPT TO:<" + to + ">");
String recipientOK = in.readLine();
System.out.println(recipientOK);
System.out.println("DATA");
out.println("DATA");
String line;
while ((line = msg.readLine()) != null) {
out.println(line);
}
System.out.println(".");
out.println(".");
String acceptedOK = in.readLine();
System.out.println(acceptedOK);
System.out.println("QUIT");
out.println("QUIT");
return true;
}
}
}
Rewrote the code. This works fine.
public class TotalTemp
{
private static DataOutputStream dos;
public static void main(String[] args) throws Exception
{
int delay = 1000;
String user = "xxxxx#gmail.com";
String pass = "xxxxxxxx11";
String username = Base64.encodeBase64String(user.getBytes(StandardCharsets.UTF_8));
String password = Base64.encodeBase64String(pass.getBytes(StandardCharsets.UTF_8));
SSLSocket sock = (SSLSocket)((SSLSocketFactory)SSLSocketFactory.getDefault()).createSocket("smtp.gmail.com", 465);
// Socket sock = new Socket("smtp.gmail.com", 587);
final BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
(new Thread(new Runnable()
{
public void run()
{
try
{
String line;
while((line = br.readLine()) != null)
System.out.println("SERVER: "+line);
}
catch (IOException e)
{
e.printStackTrace();
}
}
})).start();
dos = new DataOutputStream(sock.getOutputStream());
send("EHLO smtp.gmail.com\r\n");
Thread.sleep(delay);
send("AUTH LOGIN\r\n");
Thread.sleep(delay);
send(username + "\r\n");
Thread.sleep(delay);
send(password + "\r\n");
Thread.sleep(delay);
send("MAIL FROM:<XXXXXXXX#gmail.com>\r\n");
//send("\r\n");
Thread.sleep(delay);
send("RCPT TO:<YYYYYYYY#gmail.com>\r\n");
Thread.sleep(delay);
send("DATA\r\n");
Thread.sleep(delay);
send("Subject: Email test\r\n");
Thread.sleep(delay);
send("Test 1 2 3\r\n");
Thread.sleep(delay);
send(".\r\n");
Thread.sleep(delay);
send("QUIT\r\n");
}
private static void send(String s) throws Exception
{
dos.writeBytes(s);
System.out.println("CLIENT: "+s);
}
}
First, Make sure you have turned on 'Allow Less Secure Apps' from your Gmail.
We can improve the code by ignoring the Multi-threading part by just reading the output from server. As we know from the RFC that server sends 9 lines after getting the first 'EHLO' request. So, we are just reading 9 lines with bufferedReader. Then for the next few commands, it returns only one line. So, the simplified code without multithreading will be like this :
import java.nio.charset.StandardCharsets;
import javax.net.ssl.*;
import java.io.*;
import java.util.Base64;
public class SMTP_Simplified_v2 {
// Credentials
public static String user = "xxxxxxx#gmail.com";
public static String pass = "xxxxxxxxxx";
private static DataOutputStream dataOutputStream;
public static BufferedReader br = null;
public static void main(String[] args) throws Exception {
int delay = 1000;
String username = Base64.getEncoder().encodeToString(user.getBytes(StandardCharsets.UTF_8));
String password = Base64.getEncoder().encodeToString(pass.getBytes(StandardCharsets.UTF_8));
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket("smtp.gmail.com", 465);
br = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
dataOutputStream = new DataOutputStream(sslSocket.getOutputStream());
send("EHLO smtp.gmail.com\r\n",9);
send("AUTH LOGIN\r\n",1);
send(username+"\r\n",1);
send(password+"\r\n",1);
send("MAIL FROM:<xxxxxxxx#gmail.com>\r\n",1);
send("RCPT TO:<xxxxx#gmail.com>\r\n",1);
send("DATA\r\n",1);
send("Subject: Email test\r\n",0);
send("Email Body\r\n",0);
send(".\r\n",0);
send("QUIT\r\n",1);
}
private static void send(String s, int no_of_response_line) throws Exception
{
dataOutputStream.writeBytes(s);
System.out.println("CLIENT: "+s);
Thread.sleep(1000);
// Just reading the number of lines the server will respond.
for (int i = 0; i < no_of_response_line; i++) {
System.out.println("SERVER : " +br.readLine());
}
}
}
I'm writing a simple multi threaded java proxy, but I can't seem to get the server to display what I said, or send anything back. Here is my code:
import java.io.*;
import java.net.*;
public class TcpClient {
public static void clientS( int portNumber, String request) throws Exception {
String sentence = "";
String modifiedSentence = "";
System.out.println("In client class..");
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", portNumber);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeUTF(modifiedSentence);
System.out.println("What got written to the server: "+request);
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
clientSocket.close();
//TcpServerThread tcpThread = new TcpServerThread(clientSocket);
//tcpThread.run();
}//end method
}// client class
import java.net.Socket;
import java.util.Scanner;
import java.util.StringTokenizer;
public class RequestParser extends TcpServerThread{
static String method = "";
static String endUrl = "";
static String version = "";
static String hostHeader = "";
static String host = "";
static String hostHeader1 = "";
static String host1 = "";
static String hostHeader2 = "";
static String host2 = "";
public RequestParser(Socket theSocket) {
super(theSocket);
}
static int portNumber = 80;
public int Request() {
Scanner scan = new Scanner(System.in);
System.out.println("Please type in your information, with headers separated by a space: ");
String request = scan.nextLine();//stores the HTTP request
//parses the HTTP request, gets port number if there is one
try {
portNumber = doFormattedMethodRequest(request);
TcpClient.clientS(portNumber, request);
} catch (Exception e) {
e.getMessage();
}
return portNumber;
}//end method
public static int doFormattedMethodRequest(String unformattedRequest) throws Exception{
System.out.println("In String Parser...");
StringTokenizer tokenizer = new StringTokenizer(unformattedRequest," ");
Scanner scan = new Scanner(System.in);
//gets method, loops if there isn't correct input
while (tokenizer.hasMoreElements()){
method = (String) tokenizer.nextElement();
System.out.println("method: "+method);
if (!method.equals("GET")){
System.out.println("This program only supports GET requests");
System.out.println("Your method has been changed to GET");
method = "GET";
}//end if
endUrl = (String) tokenizer.nextElement();
System.out.println("endUrl: "+endUrl);
if(!endUrl.endsWith(".html")|| !endUrl.endsWith(".com")
|| !endUrl.endsWith(".edu")||!endUrl.endsWith(".gov")||
!endUrl.endsWith(".net")||!endUrl.endsWith(".org")||
!endUrl.endsWith(".mil")){
String [] parts = endUrl.split("/");
for (int i=0;i<parts.length;i++){
host = "www."+parts[2];
if (parts[i].matches("/*[1-65535].*") == true){
String port = parts[i];
portNumber = Integer.parseInt(port);
System.out.println("Contains a port number");
System.out.println("Port Number is: "+portNumber);
}//end if
}//end for loop
}//end if
version = (String) tokenizer.nextElement();
System.out.println("version: "+version);
if (!version.endsWith("1.0")){
System.out.println("This program only supports version of 1.0");
System.out.println("Your version has been changed to 1.0");
version = "1.0";
}
System.out.println("host: "+host);
hostHeader = (String) tokenizer.nextElement();
host = (String) tokenizer.nextElement();
hostHeader1 = (String) tokenizer.nextElement();
host1 = (String) tokenizer.nextElement();
hostHeader2 = (String) tokenizer.nextElement();
host2 = (String) tokenizer.nextElement();
}//end while loop
System.out.println("OK, here is what is being sent to the server...");
System.out.print(method); System.out.print(" "+endUrl);
System.out.println(" "+version);
//System.out.print(hostHeader); System.out.println(host+endUrl);
//System.out.print(hostHeader1); System.out.print(host);
//System.out.println(hostHeader);System.out.println(host);
return portNumber;
}//end method
}//end class
import java.io.*;
import java.net.*;
class TcpServerThread extends Thread{
static Socket connectionSocket = null;
static int portNumber = 0;
public TcpServerThread(Socket theSocket){
super("TcpServerThread");
TcpServerThread.connectionSocket = theSocket;
}
public static void main(String args[]) {
System.out.println("Taking you to HTTP request input...");
RequestParser estProxy = new RequestParser(connectionSocket);
portNumber = estProxy.Request();//goes to get the user's http request
System.out.println("");
System.out.println("-----------------------------------------------------");
System.out.println("System returned "+portNumber+" as the port number.");
//create listener socket to listen for requests
ServerSocket welcomeSocket;
try {
welcomeSocket = new ServerSocket(portNumber);
System.out.println("");
System.out.println("Listening on port number "+portNumber+"...");
estProxy.run();
boolean isListening = true;
while (isListening) {
new TcpServerThread(welcomeSocket.accept()).start();
}//end while
} catch (Exception e) {
e.getMessage();
}
}//end method
public void run(){
System.out.println("Got into run method");
Socket serverSocket = new Socket();
Socket clientSocket = new Socket();
try{
InputStream inStream = clientSocket.getInputStream();
byte [] buf = new byte[9000];
int length = inStream.read(buf);
System.out.println(new String(buf,0,length));
Socket socket= new Socket("localhost",portNumber);
OutputStream outStream = socket.getOutputStream();
outStream.write(buf,0,length);
OutputStream inStream1 = clientSocket.getOutputStream();
InputStream outStream1 = socket.getInputStream();
for(int length1; (length1 = outStream1.read(buf)) != -1;){
inStream1.write(buf,0,length1);
}
inStream1.close();
outStream1.close();
outStream.close();
inStream.close();
socket.close();
}
catch(Exception e){
e.getMessage();
}
finally{
try{
clientSocket.close();
}
catch(IOException e){
e.getMessage();
}
}
}//end method
}
Most of my communication with the server is happening in the TcpServerThread class, and I'm trying to use the TcpClient class to talk to the server, send an HTTP request, and print out what the server sends back, although after I input an http request, it only parses it and then just goes blank. Any help would be much appreciated.
You're calling writeUTF() but nobody is calling readUTF(). That's the only way anyone will understand what is written.
Howver this proxy won't work. Once you've created the initial connections you need two threads per connection, one to read and write in each direction. You can't assume that the request or response are read in a single read, and you can't generally assume that there is a single request/response pair, or indeed anything like a request or response at all.
I have a client class and a server class.
If client sends message to server, server will send response back to the client, then client will print all the messages it received.
For example,
If Client sends "A" to Server, then Server will send response to client
"1111". So I use readLine() in client class to read the message from server, then client print "1111" in the console.
If Client sends "B" to Server, then Server will send response to client
"2222\n 3333". So the expected printing output from client is:
"2222"
"3333"
So the response message from server to client may have 1 line or 2 lines depending on the message it send from client to server.
My question is that how I can use readLine() to read the message that send from server to client. More specifically, if I use the following codes,
String messageFromServer;
while(( messageFromServer = inputStreamFromServer.readLine()) != null) {
println(messageFromServer);
}
It will only print the first line, and will not print anything else even if I keep sending message from client to server, because readLine() will stops once it has read the first line.
update:
More specifically, I am looking for some methods in the client class to read message that contains 1 or multiple lines from server at a time. I am wondering if there are any ways to do it in client side if I don't want to change the format of the message that sent from server to client.
update 2
To make my question more clear, I will put some sample codes in the following:
This is server:
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(1234);
} catch (IOException e) {
System.err.println("Could not listen on port: 1234.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
}
System.out.println("Connected");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String textFromClient =null;
String textToClient =null;
textFromClient = in.readLine(); // read the text from client
if( textFromClient.equals("A")){
textToClient = "1111";
}else if ( textFromClient.equals("B")){
textToClient = "2222\r\n3333";
}
out.print(textToClient + "\r\n"); // send the response to client
out.flush();
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
The client:
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
try {
socket = new Socket("localhost", 1234);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection");
}
System.out.println("Connected");
String textToServer;
while((textToServer = read.readLine())!=null){
out.print(textToServer + "\r\n" ); // send to server
out.flush();
String messageFromServer =null;
while(( messageFromServer = textToServer=in.readLine()) != null){
System.out.println(messageFromServer);
}
}
out.close();
in.close();
read.close();
socket.close();
}
private static void debug(String msg)
{
System.out.println("Client: " + msg);
}
}
You shouldn't need to change the format of the data sent by the server, and readLine() should work, but I suspect that the server is not flushing or closing the OutputStream after writing the response which could possibly explain things.
Is the call to readLine() hanging? Are you in control of the server code? If so, can you include it?
Revised classes that work as I believe you expect:
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 ClientServerTest2
{
public static void main(String[] args) throws Exception
{
Thread serverThread = new Thread(new Server());
serverThread.start();
Thread clientThread = new Thread(new Client());
clientThread.start();
serverThread.join();
clientThread.join();
}
private static class Server implements Runnable
{
#Override
public void run()
{
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(1234);
Socket clientSocket = null;
clientSocket = serverSocket.accept();
debug("Connected");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String textFromClient = null;
String textToClient = null;
textFromClient = in.readLine(); // read the text from client
debug("Read '" + textFromClient + "'");
if ("A".equals(textFromClient))
{
textToClient = "1111";
}
else if ("B".equals(textFromClient))
{
textToClient = "2222\r\n3333";
}
debug("Writing '" + textToClient + "'");
out.print(textToClient + "\r\n"); // send the response to client
out.flush();
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void debug(String msg)
{
System.out.println("Server: " + msg);
}
}
private static class Client implements Runnable
{
#Override
public void run()
{
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
try
{
socket = new Socket("localhost", 1234);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
debug("Connected");
String textToServer;
textToServer = read.readLine();
debug("Sending '" + textToServer + "'");
out.print(textToServer + "\r\n"); // send to server
out.flush();
String serverResponse = null;
while ((serverResponse = in.readLine()) != null)
debug(serverResponse); // read from server and print it.
out.close();
in.close();
read.close();
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
private static void debug(String msg)
{
System.out.println("Client: " + msg);
}
}
Change while(( messageFromServer = inputStreamFromServer.readLine() != null) to while(( messageFromServer = inputStreamFromServer.readLine()) != null)
Actually this shouldn't even compile....
It's a work around.
If you want to send multiple strings like in your case : "2222\n 3333".
You can send them by adding a seperator character (like :) between two strings : "2222: 3333".
Then you can call write from server side as
clientOut.write("2222: 3333\n");
On client side parse recieved String :
messageFromServer = inputStreamFromServer.readLine();
String strArray[] = messageFromServer.split(":");
strArray[0] : 2222
strArray[0] : 3333