I had create a new client-server connection using ordinary java socket programming:
private static BufferedReader input;
private static DataOutputStream output;
private static Socket socket;
public void connect() {
try {
socket = new Socket(address, port);
} catch (Exception e) {
e.printStackTrace();
}
}
And I'm sending and receiving the following way :
to send:
output = new DataOutputStream(socket.getOutputStream());
output.writeBytes(data);
to receive:
InputStream stream = null;
try{
stream = socket.getInputStream();
}catch(Exception e){
e.printStackTrace();
}
if(stream != null){
input = new BufferedReader(new InputStreamReader(
stream));
// some input processing
}
The problem is when The connection is interrupted some how I have to relaunch it again in the app run-time, so I made a thread in order to re-execute the connect() method, and It executed efficiently without any Exceptions, but then , the input and output variables fail to send or receive any data.
It sounds like you are reconnecting your socket without recreating your input and output streams.
Try running recreating your input and output streams after you run connect() like so:
output = new DataOutputStream(socket.getOutputStream());
stream = socket.getInputStream();
you can try cleaning the input and output stream in finally and also close the socket...
finally { socket.close(); }
Related
I have created this code snippet in both a single threaded version and multithreaded for a client/server setup I have going. I have tested both (recording the avg turn around time) and have gotten EXTREMELY similar results within margin of error when running multiple simple server commands at once. have I implememnted my client handler wrong?
This is my first time trying to implement a multithreaded server and from my understanding it just a matter of putting in a client handler being
`
class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
`
below is the snippet of the whole server code.
`
public class Server {
public static void main(String[] args) {
if (args.length < 1) return;
int port = Integer.parseInt(args[0]);
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server is listening on port " + port);
while (true) {
Socket socket = serverSocket.accept();
System.out.println("New client connected");
new ServerThread(socket).start();
}
} catch (IOException ex) {
System.out.println("Server exception: " + ex.getMessage());
ex.printStackTrace();
}
}
}
class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
try {
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
OutputStream output = socket.getOutputStream();
PrintWriter writer = new PrintWriter(output, true);
String text;
do {
text = reader.readLine(); // reads text from client
Process p = Runtime.getRuntime().exec(text);
BufferedReader stdout = new BufferedReader(new InputStreamReader(p.getInputStream()));
String outputLine;
while ((outputLine = stdout.readLine()) != null) { // while serverMsg is not empty keep printing
writer.println(outputLine);
}
stdout.close();
writer.println("ENDCMD");
// Text here should just write back directly what the server is reading...?
}
while (!text.toLowerCase().equals("exit"));
socket.close();
} catch (IOException ex) {
System.out.println("Server exception: " + ex.getMessage());
ex.printStackTrace();
}
}
}
`
I have tested both (recording the avg turn around time) and have gotten EXTREMELY similar results within margin of error when running multiple simple server commands at once. have I implememnted my client handler wrong?
If you are not making a new connection for each command that you send, then this would be expected. Since each connection runs on one thread, a multi-threaded approach, as you have shown, would have the same speed as if you didn't make a new thread for each connection. The difference is that, without multi-threading, you can only have one connection at a time.
im trying to listen on HTTP requests for an website in my application. My application is used to extract some data from the inputstream of Socket1 and forward it to the output stream of another socket2 (the client socket2 which connects to the actual webserver). The webserver should anser (->Inputstream2) and i want to pass it back to outputstream1 of socket1.
The real webserver is getting an request, but im not receiving an answer, in this constellation. I read, that i have to close the output stream of an socket bevor can start to read the inputstream, so I also tried socket.shutdownOutput() but it's still not working.
I would appriciate any help
private static void runHttpListener(Boolean simulate){
try {
ServerSocket server = new ServerSocket(PORT_HTTP_REQUEST);
System.out.println("HTTP listener active on Port "+PORT_HTTP_REQUEST);
boolean keepAlive = true;
while (keepAlive) {
//Empfangen und auslesen
Socket socketReceivingProxy = server.accept();
System.out.println("HTTP-Listener: Accepted client connection");
InputStream proxyInputStream = socketReceivingProxy.getInputStream();
OutputStream proxyOutputStream = socketReceivingProxy.getOutputStream();
//TODO: extract information from stream
//forward
InputStream result = sendHttpRequestToDestination(proxyInputStream, simulate);
result.transferTo(proxyOutputStream);
result.close();
proxyOutputStream.close();
socketReceivingProxy.close();
}
server.close();
System.out.println("HTTP listener closed");
} catch (Exception e) {
e.printStackTrace();
}
My forwarding method is realy simple but it doesn't actually works:
private static InputStream sendHttpRequestToDestination(InputStream incomingRequest, Boolean simulate){
try{
Socket socketForwardingWebapp = new Socket(simulate?URL_WEB_SERVER_SIMULATION:URL_WEB_SERVER,
simulate?PORT_WEB_SERVER_SIMULATION:PORT_WEB_SERVER);
System.out.println("HTTP-Forwarding: Created socket "+socketForwardingWebapp.getInetAddress()+":"+socketForwardingWebapp.getPort());
InputStream webappInputStream = socketForwardingWebapp.getInputStream();
OutputStream outputStream = socketForwardingWebapp.getOutputStream();
if(incomingRequest.available()>0){
System.out.println("Incoming Request can be forwarded");
long bytesTransfered = incomingRequest.transferTo(outputStream);
System.out.print("stream copied");
socketForwardingWebapp.shutdownOutput();
System.out.println("Bytes forwareded: "+bytesTransfered);
}
return webappInputStream;
}catch(Exception exc){
exc.printStackTrace();
}
return null;
}
I solved this problem using Threads. Here is what worked:
private static Thread inputStreamToOutputStream(InputStream inputStream, OutputStream outputStream){
Thread t = new Thread(() -> {
long transferedBytes = 0;
try {
transferedBytes = inputStream.transferTo(outputStream);
inputStream.close();
outputStream.close();
System.out.println("StreamTransformer: Bytes forwareded: "+transferedBytes);
} catch (IOException e) {
System.out.println("StreamTransformer: Error accoured while transforming");
}
});
t.start();
return t;
}
Used this new method like this:
private static Thread sendHttpRequestToDestination(InputStream incomingRequest, OutputStream outgoingAnswer, Boolean simulate){
Thread t = new Thread(){
public void run(){
try{
Socket socketForwardingWebapp = new Socket(simulate?URL_WEB_SERVER_SIMULATION:URL_WEB_SERVER,
simulate?PORT_WEB_SERVER_SIMULATION:PORT_WEB_SERVER);
System.out.println("HTTP-Forwarding: Created socket "+socketForwardingWebapp.getInetAddress()+":"+socketForwardingWebapp.getPort());
InputStream webappInputStream = socketForwardingWebapp.getInputStream();
OutputStream outputStream = socketForwardingWebapp.getOutputStream();
if(incomingRequest.available()>0){
System.out.println("HTTP-Forwarding: Incoming Request can be forwarded");
Thread send = inputStreamToOutputStream(incomingRequest, outputStream);
Thread receive = inputStreamToOutputStream(webappInputStream, outgoingAnswer);
send.join();
System.out.println("HTTP-Forwarding: successfuly sent");
receive.join();
System.out.println("HTTP-Forwarding: successfuly received");
}
socketForwardingWebapp.close();
}catch(Exception exc){
exc.printStackTrace();
}
}
};
t.start();
return t;
}
I am a student and learning Network Programming and have a some problem.
This is my client:
public class Test2Client_Tranfer_An_Obj {
Socket socket = null;
ObjectOutputStream out;
ObjectInputStream in;
public Test2Client_Tranfer_An_Obj() {
try {
socket = new Socket("localhost", 12345);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
System.out.println("Ready");
System.out.println("" + in.readUTF());
System.out.println("" + in.readUTF());
System.out.println("Recived");
out.writeUTF("hihi");
System.out.println("Sended");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("Client");
Test2Client_Tranfer_An_Obj test = new Test2Client_Tranfer_An_Obj();
}
}
This my Server:
public class Test2Server_Tranfer_An_Obj {
ServerSocket serverSocket;
ObjectOutputStream out;
ObjectInputStream in;
public Test2Server_Tranfer_An_Obj() {
try {
serverSocket = new ServerSocket(12345);
Socket socket = serverSocket.accept();
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
System.out.println("Ready!");
out.writeUTF("huhu");
out.writeUTF("hoho");
System.out.println("Sended");
String s = in.readUTF();
System.out.println("" + s);
System.out.println("Recived");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("Server");
Test2Server_Tranfer_An_Obj demo = new Test2Server_Tranfer_An_Obj();
}
}
But, when i run my program, this result:
Server Console
Server
Ready!
Sended
Client Console
Client Ready
Anybody can tell me why and what i can do?
Thank for reading!
Hope recive you answer
Object Stream is overkill in this case. You are not actually using writeObject/readObject and using DataInputStream and DataOutputStream would do what you want.
In this particular case, an Object Stream is buffered, which means that small writes are buffered until you either flush() or close() the stream to improve performance. As you don't do either, the writeUTF only writes to memory, not the Socket.
c.f. Data Streams are not buffered by default.
In your server after write to the outputstream. you have to add out.flush() to write to socket
First of all, the android application will connect to the server (PC).
Then the android will send a message.
And finally the android application should receive a message from the server.
When I send the message from the android to the Server, everything goes well.
However, when it comes to reading from socket inside the android app, I can't receive anything.
Here is the Server code
ServerSocket Sock = new ServerSocket(7777);
System.out.println("Waiting for connection...\n");
Socket connectionSocket = Sock.accept();
System.out.println("Client In...");
BufferedReader inFromClint = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
PrintWriter printwriter = new PrintWriter(connectionSocket.getOutputStream());
String txt = inFromClint.readLine();
System.out.println(txt);
String MsgToClient = "{\"LoginFlag\":\"N\"}"; //{"LoginFlag":"P"}
printwriter.write(MsgToClient);
printwriter.flush();
printwriter.close();
System.out.println("\nMsg Sent");
Sock.close();
And this is sample of the Android app:
new Thread(new Runnable() {
#Override
public void run() {
try
{
BufferedReader bufferedReader = null;
PrintWriter printwriter = null;
port = 7777;
client = new Socket("192.168.1.2", port);
printwriter = new PrintWriter(client.getOutputStream());
printwriter.write(SMsgLog);
printwriter.flush();
printwriter.close();
bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
if( bufferedReader.ready() )
{
RJasonLog = bufferedReader.readLine(); //rcv as jason
}
else
{
RJasonLog = null;
}
if (RJasonLog != null)
{
JSONObject objectRcv = new JSONObject(RJasonLog);
if (objectRcv != null)
{
RMsgLog = objectRcv.getString("LoginFlag"); //Jason Key from the server
}
}
RMsgLog = "N";
if(RMsgLog.equals("N"))
{
alert.showAlertDialog(Login.this, "Login failed..", "Username/Password is incorrect", false);
}
else
alert.showAlertDialog(Login.this, "Login failed..", "Please Try Again", false);
client.close();
}
catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
The clienr is trying to read a line. But the server is not sending a line with printwriter.write(MsgToClient);. Change to printwriter.write(MsgToClient + "\n"); to send a line.
I solved it with the help from the comments.
I removed printwriter.close(); on client side.
And then I added \n In both client and server before sending the message
Don't close the output stream in client code, Remove this line:
printwriter.close();
Stream should not be closed until connection is alive. It should be closed at the end when you are done with the socket. Closing connection will also close the streams associated with it.
Here is small description about the getOutputStream method.
getOutputStream
public OutputStream getOutputStream() throws IOException Returns an
output stream for this socket. If this socket has an associated
channel then the resulting output stream delegates all of its
operations to the channel. If the channel is in non-blocking mode then
the output > stream's write operations will throw an
IllegalBlockingModeException.
Closing the returned OutputStream will close the associated socket.
Returns: an output stream for writing bytes to this socket. Throws:
IOException - if an I/O error occurs when creating the output stream
or if the socket is not connected.
I'm trying to get a simple multithreaded proxy to work in Java. However I don't manage to get the webpage show up in my browser, after the first GET request and the response from the webpage, the program is just stuck (as you can see from my code, I'm printing everything i get on the stdout for debugging, and there I see the sourcecode of the webpage, however after printing out "After Client Write", nothing happens (no exception, just nothing...)).
import java.net.*;
import java.util.*;
import java.io.*;
public class Proxy
{
public static void main(String[] args)
{
try
{
ServerSocket listensocket = new ServerSocket(Integer.valueOf(args[0]));
while(true)
{
System.out.println("wait");
Socket acceptsocket = listensocket.accept(); // blocking call until it receives a connection
myThread thr = new myThread(acceptsocket);
thr.start();
}
}
catch(IOException e)
{
System.err.println(">>>>" + e.getMessage() );
e.printStackTrace();
}
}
static class myThread extends Thread
{
Socket acceptsocket;
int host, port;
String url;
myThread(Socket acceptsocket)
{
this.acceptsocket=acceptsocket;
}
public void run() {
try
{
System.out.println("hello");
Socket client = acceptsocket;
//client.setSoTimeout(100);
InputStream clientIn = client.getInputStream();
//BufferedInputStream clientIn=new BufferedInputStream(clientis);
OutputStream clientOut = client.getOutputStream();
System.out.println("hello");
String clientRequest = readStuffFromClient(clientIn); // parses the host and what else you need
System.out.print("Client request: -----\n"+clientRequest);
Socket server;
server = new Socket("xxxxxxxxxxxxx" , 80);
InputStream serverIn = server.getInputStream();
//BufferedInputStream serverIn=new BufferedInputStream(serveris);
OutputStream serverOut = server.getOutputStream();
serverOut.write(clientRequest.getBytes());
serverOut.flush();
String serverResponse = readStuffFromClient(serverIn);
System.out.print("Server Response: -----\n"+serverResponse);
clientOut.write(serverResponse.getBytes());
clientOut.flush();
System.out.println("After Client Write");
clientIn.close();
clientOut.close();
serverIn.close();
serverOut.close();
server.close();
client.close();
}
catch(Exception e)
{
System.out.println(e);
}
}
private String readStuffFromClient(InputStream clientdata)
{
ByteArrayOutputStream response = new ByteArrayOutputStream();
StringBuffer request=new StringBuffer(8192);
int i, httpstart,n=-1 ;
byte[] buffer = new byte[8192];
System.out.println("beforetry");
try
{
while((n = clientdata.read(buffer))!=-1)
{
System.out.println("before");
response.write(buffer,0,n);
//response.flush();
}
request=new StringBuffer(response.toString());
/*System.out.println("new:"+n+" "+ request.toString());
System.out.println("End client data");*/
}
catch (Exception e)
{
System.out.println("here");
System.out.println(e);
e.printStackTrace();
i = -1;
}
System.out.println("End manipulation method");
return request.toString();
}
}
}
(this is a stripped down not working example of my program, from the comments one can see I already tried to use BufferedInputStream). In general, this program is very unresponsive even for the first GET request from the browser. When I only read the clientdata once (not in a loop), I get a little bit further, e.g. get more GET/Response pairs, but at some point the program still gets stuck.
Somehow I think either I've a real trivial error I just don't manage to see, or the program should work, but simply doesn't for no real reason.
Any help is appreciated, thanks in advance!
You need two threads: one to read from the client and write to the server, and one to do the opposite, for each accepted socket. There is a further subtlety: when you read EOS from one direction, shutdown the opposite socket for output, and then if the input socket for that thread is already shutdown for output, close both sockets. In both cases exit the thread that read the EOS.
Try getting first the OutputStream and then the InputStream!
InputStream clientIn = client.getInputStream();
OutputStream clientOut = client.getOutputStream();
change it to:
OutputStream clientOut = client.getOutputStream();
InputStream clientIn = client.getInputStream();
This will make it work:
It will check if there is more data available to read
Still, it's important that you use BufferedIS because I think ByteArrayIS doesn't implement available method.
BufferedInputStream bis = new BufferedInputStream(clientdata);
System.out.println("beforetry");
try {
while(bis.available() > 0){
n = bis.read(buffer);
response.write(buffer, 0, n);
}