proxy server in java - java

i have the follwoing code of proxy server. IS if the right approach? Will this be able to handel load/trafffic if deployed comerially??
package proxyserver;
import com.sun.corba.se.spi.activation.Server;
import java.net.* ;
import java.io.* ;
import java.lang.* ;
import java.util.* ;
/**
*
* #author user
*/
public class Main {
/**
* #param args the command line arguments
*/
// Variable to track if an error occurred
boolean errorOccurred = false;
//Variables for the host and port parameters
public static void main(String[] args) {
// TODO code application logic here
int localPort = -1;
int remotePort = -1;
String remoteHost = "www.youtube.com";
System.out.print("dwdsw");
Integer parseLocalPort = new Integer(555);
Integer parseRemotePort = new Integer(80);
localPort =80 ;
remotePort = 80;
//Create a listening socket at proxy
ServerSocket server = null;
try
{
server = new ServerSocket(localPort);
}
catch(IOException e)
{
System.err.println("Error: " + e.getMessage());
System.exit(-1);
}
//Loop to listen for incoming connection,
//and accept if there is one
Socket incoming = null;
Socket outgoing = null;
while(true)
{
try
{
// Create the 2 sockets to transmit incoming
// and outgoing traffic of proxy server
incoming = server.accept();
outgoing = new Socket(remoteHost, remotePort);
// Create the 2 threads for the incoming
// and outgoing traffic of proxy server
ProxyThread thread1 = new ProxyThread(incoming, outgoing);
thread1.start();
ProxyThread thread2 = new ProxyThread(outgoing, incoming);
thread2.start();
}
catch (UnknownHostException e)
{
System.err.println("Error: Unknown Host " + remoteHost);
System.exit(-1);
}
catch(IOException e)
{
//continue
System.exit(-2);;
}
}
}
}
now proxy classs
package proxyserver;
/**
*
* #author user
*/
import java.net.* ;
import java.io.* ;
import java.lang.* ;
import java.util.* ;
class ProxyThread extends Thread
{
Socket incoming, outgoing;
ProxyThread(Socket in, Socket out)
{
incoming = in;
outgoing = out;
}
// Overwritten run() method of thread,
// does the data transfers
public void run()
{
byte[] buffer = new byte[5000];
int numberRead = 0;
OutputStream toClient;
InputStream fromClient;
try{
toClient = outgoing.getOutputStream();
fromClient = incoming.getInputStream();
while(true)
{
numberRead = fromClient.read(buffer, 0, 50);
if(numberRead == -1)
{
incoming.close();
outgoing.close();
}
String st = new String(buffer,"US-ASCII");
System.out.println("\n\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n\nXXXXXXXXXXXXXXXX\n\n" + st);
toClient.write(buffer, 0, numberRead);
}
}
catch(IOException e)
{
}
catch(ArrayIndexOutOfBoundsException e)
{
}
}
}

[ OK ... enough teasing :-) ]
It looks like it should work, though:
The stuff that you print to System.err in the Proxy class may be mangled. (As I said before, you cannot just assume that every web page is encoded in ASCII!!)
You should probably be reading much more than 50 bytes at a time .... especially if you want high throughput.
Your main class probably should be using a thread pool rather than creating and throwing away threads. And you probably should put an upper bound on the number of threads you want to allow at any given time.
You probably need to do something about servers that take a long time to deliver their responses, etcetera.
Finally, in response to this:
Will this be able to handle the
load/traffic if it is deployed commercially??
It is impossible to say how much load you could pump through this program. For a start, it will depend on your processor and network interface hardware.

It looks about right in principle but you should take a look at an open source version like TCP Proxy for pointers on maximizing throughput, increasing resilience, etc.

Related

Java Eclipse - Output when running from command prompt is not the same as through IDE [duplicate]

This question already exists:
Java Eclipse - Output when running from command prompt is not the same as through IDE
Closed 4 years ago.
this was asked on superuser https://superuser.com/questions/1364594/java-eclipse-output-when-running-from-command-prompt-is-not-the-same-as-throug but I was told to ask here instead.
I am very new to Java and the eclipse IDE and have an issue when running my Java code from the command prompt on Windows. If I run the code through the eclipse IDE this is the output I get
Message number 0
Message number 1
Message number 2
Timeout. Client is closing.
However, if I run the code through the command prompt java test.Main, I get a lot of empty lines between the messages on the command prompt.
//Hundreds of empty lines
Message number 0
//Hundreds of empty lines
Message number 1
//Hundreds of empty lines
Message number 2
//Hundreds of empty lines
Timeout. Client is closing.
I have tried adding simple checks to not print any output if the string is either NULL or empty but it has not worked. Below is my code. I have spent quite a lot of time on this but have no idea what is causing it.
Main.java
package test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
// create 5 processes
public class Main {
public static void main(String[] args) {
int port = 50001;
UdpUnicastServer server = new UdpUnicastServer(port);
UdpUnicastClient client = new UdpUnicastClient(port);
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(client);
executorService.submit(server);
}
}
UdpUnicastClient.java
package test;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* Created by dan.geabunea on 6/3/2016.
*/
public class UdpUnicastClient implements Runnable {
private final int port;
public UdpUnicastClient(int port) {
this.port = port;
}
#Override
public void run() {
/**
* Bind the client socket to the port on which you expect to
* read incoming messages
*/
try (DatagramSocket clientSocket = new DatagramSocket(port)) {
/**
* Create a byte array buffer to store incoming data. If the message length
* exceeds the length of your buffer, then the message will be truncated. To avoid this,
* you can simply instantiate the buffer with the maximum UDP packet size, which
* is 65506
*/
byte[] buffer = new byte[65507];
// Set a timeout of 3000 ms for the client.
clientSocket.setSoTimeout(3000);
while (true) {
DatagramPacket datagramPacket = new DatagramPacket(buffer, 0, buffer.length);
/**
* The receive method will wait for 3000 ms for data.
* After that, the client will throw a timeout exception.
*/
clientSocket.receive(datagramPacket);
String receivedMessage = new String(datagramPacket.getData());
if(receivedMessage != null && !receivedMessage.isEmpty()) {
System.out.println(receivedMessage);
}
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("Timeout. Client is closing.");
}
}
}
UdpUnicastServer.java
package test;
import java.io.IOException;
import java.net.*;
/**
* Created by dan.geabunea on 6/3/2016.
*/
public class UdpUnicastServer implements Runnable {
/**
* The port where the client is listening.
*/
private final int clientPort;
public UdpUnicastServer(int clientPort) {
this.clientPort = clientPort;
}
#Override
public void run() {
/**
* Create a new server socket and bind it to a free port. I have chosen
* one in the 49152 - 65535 range, which are allocated for internal applications
*/
try (DatagramSocket serverSocket = new DatagramSocket(50000)) {
// The server will generate 3 messages and send them to the client
for (int i = 0; i < 3; i++) {
String message = "Message number " + i;
DatagramPacket datagramPacket = new DatagramPacket(
message.getBytes(),
message.length(),
InetAddress.getLocalHost(),
clientPort
);
serverSocket.send(datagramPacket);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I suspect a Charset (encoding) problem.
Try passing a Charset name to both String.getBytes() in the server app, and the String constructor in the client app, e.g.
byte[] bytes = message.getBytes("UTF-8");
DatagramPacket datagramPacket = new DatagramPacket(
bytes,
bytes.length,
InetAddress.getLocalHost(),
clientPort
);
and
String receivedMessage = new String(datagramPacket.getData(), "UTF-8");
Edit - also make sure that you're using the correct length for the outbound datagram, recognizing that the length of the string in chars is not necessarily the length of the byte array (in bytes). Updated the example code.

Java Publisher Sever chat program

I am trying to create a chat application which has one publisher, one server and multiple subscribers. The publisher(Sending to port 8000) sends a message to the server(listening on port 8000 and 5000) and which forwards it further to the subscriber(listening on port 5000).
Now so far I can create multiple publishers and the communication between server and publisher is working, however, I am not able to send it to the subscriber the message sent by the publisher
Server Side Code
package serverclient;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server extends Thread{
private Socket socket;
private int clientNumber;
public Server(Socket socket, int clientNumber){
this.socket = socket;
this.clientNumber = clientNumber;
if(socket.getLocalPort() == 5000)System.out.print("\nSubscriber "+ clientNumber +" is connected to the server");
if(socket.getLocalPort() == 8000)System.out.print("\nPublisher "+ clientNumber +" is connected to the server");
}
#Override
public void run(){
try {
BufferedReader dStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while(true){
synchronized(this){
String clMessage = dStream.readLine();
System.out.println("\n"+clMessage);
// if(socket.getLocalPort() == 5000){
out.println("Hey the server is sending the message to subscriber");
// }
//out.println("Hey the publisher has sent the message : " + clMessage);
}
}
} catch (IOException ex) {
System.out.print("\nError has been handled 1\n");
}finally{
try {
socket.close();
} catch (IOException ex) {
System.out.print("\nError has been handled 2\n");
}
}
}
public static void main(String [] args) throws IOException{
int subNumber = 0;
int pubNumber = 0;
ServerSocket servSockpub = new ServerSocket(8000);
ServerSocket servSocksub = new ServerSocket(5000);
try {
while (true) {
Server servpub = new Server(servSockpub.accept(),++pubNumber);
servpub.start();
System.out.print("\nThe server is running on listen port "+ servSockpub.getLocalPort());
Server servsub = new Server(servSocksub.accept(),++subNumber);
servsub.start();
System.out.print("\nThe server is running on listen port "+ servSocksub.getLocalPort());
}
} finally {
servSockpub.close();
servSocksub.close();
}
}
}
publisher code
package serverclient;
import java.net.*;
import java.io.*;
public class Publisher {
public static void main (String [] args) throws IOException{
Socket sock = new Socket("127.0.0.1",8000);
// reading from keyboard (keyRead object)
BufferedReader keyRead = new BufferedReader(new InputStreamReader(System.in));
// sending to client (pwrite object)
OutputStream ostream = sock.getOutputStream();
PrintWriter pwrite = new PrintWriter(ostream, true);
InputStream istream = sock.getInputStream();
BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));
System.out.println("Start the chitchat, type and press Enter key");
String receiveMessage,sendMessage;
while(true)
{
sendMessage = keyRead.readLine(); // keyboard reading
pwrite.println(sendMessage); // sending to server
pwrite.flush(); // flush the data
if((receiveMessage = receiveRead.readLine()) != null) //receive from server
{
System.out.println(receiveMessage); // displaying at DOS prompt
}
else{
System.out.print("Null");
}
}
}
}
subscriber
package serverclient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class Subscriber {
public static void main (String [] args) throws IOException{
Socket sock = new Socket("127.0.0.1",5000);
// receiving from server ( receiveRead object)
InputStream istream = sock.getInputStream();
BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));
System.out.println("Recive side");
String receiveMessage, sendMessage;
while(true)
{
System.out.print("Hey man " + receiveRead.readLine() + "\n");
if((receiveMessage = receiveRead.readLine()) != null) //receive from server
{
System.out.println(receiveMessage); // displaying at DOS prompt
}
else{
System.out.print("Null");
}
}
}
}
Any help is appreciated. I just want to figure out why subscriber is not reciveing message
There are many possibilities to handle realm time communication issues. I myself prefer the use of Events / EventListeners.
Currently in your program there is no communication between the Server as such and the threads which handle the subscriber connection.
Also on a side node: even with a proper communication between publisher connection threads and subscriber connection threads it won't work now since you are using the same Server class. This does not only violate the Single-Responsibility-Principle but will also prevent the server from ever sending a message to the Subscriber.
Let's say you have establish a connection and your server class is now connected with the subscriber. What will happen?
The subscriber will loop until there is a message on the input stream of his socket. Good that is exactly what we want. But what does the server do? The truth is exactly the same. The first few statements in the try block of your Server's run method are to create a BufferedReader and read from it until a message receives. And now we have a socket on each site which will infinitly wait for some kind of message to arrive (which will obviously never happen since both are waiting for something).
To prevent this you should check if there is anything to read on the stream first:
while ( true )
{
if ( socket.getInputStream().available() != 0 )
{
// reading logic goes here....
synchronized ( this )
{
String clMessage = dStream.readLine();
System.out.println( "\n" + clMessage );
out.println( "Hey the server is sending the message to subscriber" );
}
}
// what shall be done when not reading.
}
Now the second part. If you want to communicate between threads you need to implement some logic to do so. As stated above I love the concept of Listeners so i will show an example where I make use of them:
MessageReceivedListener.java
import java.util.EventListener;
public interface MessageReceivedListener
extends EventListener
{
public void onMessageReceived( String message );
}
Note: The interface does not have to extend EventListener since EventListener
is just a tagging interface. I myself still prefer to have this as a reminder for what purpose the interface is there.
Server.java (excerpt)
// New constructor since we will pass a Listener now. Also new local variable for it.
public Server( Socket socket, int clientNumber, MessageReceivedListener mrl )
{
this.socket = socket;
this.clientNumber = clientNumber;
this.mrl = mrl;
if ( socket.getLocalPort() == 5000 )
System.out.print( "\nSubscriber " + clientNumber + " is connected to the server" );
if ( socket.getLocalPort() == 8000 )
System.out.print( "\nPublisher " + clientNumber + " is connected to the server" );
}
The new constructor provides a way to pass the MessageReceivedListener to the Server object. Alternatively you can alsocreate a setter for it.
synchronized ( this )
{
String clMessage = dStream.readLine();
System.out.println( "\n" + clMessage );
out.println( "Hey the server is sending the message to subscriber" );
mrl.onMessageReceived( clMessage );
}
This is where the magic happens. After whe receive the message we just pass it to the onMessageReceived(String message) method of the listener. But what does it do exactly? This is what we define when creatinga Server object.
Here are two examples, one with anonymous classes (Java 7 and before) and on with lambdas (Java 8 and later).
Example Java 7 and earlier
Server servpub = new Server( servSockpub.accept(), ++pubNumber,
new MessageReceivedListener()
{
#Override
public void onMessageReceived( String message )
{
// call nother local method
// this method would need to be a static method of Server
// because it's in the scope of your server class
sendMessageToSubscribers(message);
}
} );
Here we pass an anonymous class as our MessageReceivedListener object and define it's behaviour (in this case just calling another method which will handle the rest.
Now since our MessageReceivedListener interface does only contain one method we can also see it as a functional interface and therefore use lambdas to shorten the code and improve readability.
Example with Lambda (Java 8 and later)
Server servpub = new Server( servSockpub.accept(), ++pubNumber, Server::sendMessageToSubscribers);
In this specific case we only have one argument which we want to pass to a method and therefore can use a method reference.
How to actually implement the method sendMessageToSubs(String message) is up to you. But you need to keep track of how many Threads with subscriber connections have been created and how you want to reference them.

Extracting Content from InputStream

My goal here is to make a simple HTTP proxy that can perform GET/POST requests, trying to learn about Java Sockets. Would be appreciated if anyone can point me in that direction.
// This example is from _Java Examples in a Nutshell_. (http://www.oreilly.com)
// Copyright (c) 1997 by David Flanagan
// This example is provided WITHOUT ANY WARRANTY either expressed or implied.
// You may study, use, modify, and distribute it for non-commercial purposes.
// For any commercial use, see http://www.davidflanagan.com/javaexamples
import java.io.*;
import java.net.*;
/**
* This class implements a simple single-threaded proxy server.
**/
public class SimpleProxyServer {
/** The main method parses arguments and passes them to runServer */
public static void main(String[] args) throws IOException {
try {
// Check the number of arguments
if (args.length != 3)
throw new IllegalArgumentException("Wrong number of arguments.");
// Get the command-line arguments: the host and port we are proxy for
// and the local port that we listen for connections on
String host = args[0];
int remoteport = Integer.parseInt(args[1]);
int localport = Integer.parseInt(args[2]);
// Print a start-up message
System.out.println("Starting proxy for " + host + ":" + remoteport +
" on port " + localport);
// And start running the server
runServer(host, remoteport, localport); // never returns
}
catch (Exception e) {
System.err.println(e);
System.err.println("Usage: java SimpleProxyServer " +
"<host> <remoteport> <localport>");
}
}
/**
* This method runs a single-threaded proxy server for
* host:remoteport on the specified local port. It never returns.
**/
public static void runServer(String host, int remoteport, int localport)
throws IOException {
// Create a ServerSocket to listen for connections with
ServerSocket ss = new ServerSocket(localport);
// Create buffers for client-to-server and server-to-client communication.
// We make one final so it can be used in an anonymous class below.
// Note the assumptions about the volume of traffic in each direction...
final byte[] request = new byte[1024];
byte[] reply = new byte[4096];
// This is a server that never returns, so enter an infinite loop.
while(true) {
// Variables to hold the sockets to the client and to the server.
Socket client = null, server = null;
try {
// Wait for a connection on the local port
client = ss.accept();
// Get client streams. Make them final so they can
// be used in the anonymous thread below.
final InputStream from_client = client.getInputStream();
final OutputStream to_client= client.getOutputStream();
// Make a connection to the real server
// If we cannot connect to the server, send an error to the
// client, disconnect, then continue waiting for another connection.
try { server = new Socket(host, remoteport); }
catch (IOException e) {
PrintWriter out = new PrintWriter(new OutputStreamWriter(to_client));
out.println("Proxy server cannot connect to " + host + ":" +
remoteport + ":\n" + e);
out.flush();
client.close();
continue;
}
// Get server streams.
final InputStream from_server = server.getInputStream();
final OutputStream to_server = server.getOutputStream();
// Make a thread to read the client's requests and pass them to the
// server. We have to use a separate thread because requests and
// responses may be asynchronous.
Thread t = new Thread() {
public void run() {
int bytes_read;
try {
while((bytes_read = from_client.read(request)) != -1) {
to_server.write(request, 0, bytes_read);
to_server.flush();
}
}
catch (IOException e) {}
// the client closed the connection to us, so close our
// connection to the server. This will also cause the
// server-to-client loop in the main thread exit.
try {to_server.close();} catch (IOException e) {}
}
};
// Start the client-to-server request thread running
t.start();
// Meanwhile, in the main thread, read the server's responses
// and pass them back to the client. This will be done in
// parallel with the client-to-server request thread above.
int bytes_read;
try {
while((bytes_read = from_server.read(reply)) != -1) {
to_client.write(reply, 0, bytes_read);
to_client.flush();
}
}
catch(IOException e) {}
// The server closed its connection to us, so close our
// connection to our client. This will make the other thread exit.
to_client.close();
}
catch (IOException e) { System.err.println(e); }
// Close the sockets no matter what happens each time through the loop.
finally {
try {
if (server != null) server.close();
if (client != null) client.close();
}
catch(IOException e) {}
}
}
}
}
Code obtained from http://examples.oreilly.com/jenut/SimpleProxyServer.java
I was wondering how I would be able to extract the HOSTNAME from the inputstream and use that information extracted to pass to the method below.
try { server = new Socket(host, remoteport); }
catch (IOException e) {
PrintWriter out = new PrintWriter(new OutputStreamWriter(to_client));
out.println("Proxy server cannot connect to " + host + ":" +
remoteport + ":\n" + e);
out.flush();
client.close();
continue;
}
I've tried creating a method that converts the InputStream into a String format but it seems to make the program get stuck after assigning it to the variable. (Tried something like this over here - Read/convert an InputStream to a String)
You can create a separate ByteArrayOutputStream to get the information from the InputStream.
...
final OutputStream to_client= client.getOutputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
...
And then in the while loop you can write to baos as well
...
while((bytes_read = from_server.read(reply)) != -1) {
to_client.write(reply, 0, bytes_read);
to_client.flush();
baos.write(reply, 0, bytes_read);
}
baos.flush();
...
And you can finally get the string from baos.
String requestString = new String(baos.toByteArray());
Then, you can search the Host header by doing this:
String[] headers = requestString.split("\n");
for (int i = 0; i < headers.length; i++) {
if (headers[i].startsWith("Host")) {
String[] hostHeader = headers[i].split(":");
if (hostHeader.length > 1) {
host = hostHeader[1];
}
}
}

Messaging between Android and Desktop

I'm trying to make an Android app that's able to send a message to a computer and receive one from it. It's pretty basic. The thing is, I have accomplished this through multicasting, although not exactly. My app is able to receive messages from the computer (which uses a java application I made to receive and send the messages). But, when I try to send a message from the device to the computer, the message doesn't arrive to the computer. I mean, to the application.
Both the desktop app and the Android app use the same Client - Server classes. This is what gets me so confused. Because, as I am using the same classes, why does it work one way but not the other? I just don't no.
The desktop app runs on windows.
Also, when the Android app receives a message, it receives it the following way: "Message 1���������������������������..." when the message should be received: "Message 1". I don't know if this could be relevant.
The code is the following:
Server Class:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class MulticastSocketServer implements Runnable{
final static String INET_ADDR = "224.0.0.3";
final static int PORT = 8888;
static String msg;
public MulticastSocketServer(String message) throws UnknownHostException, InterruptedException {
msg = message;
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
// TODO Auto-generated method stub
// Get the address that we are going to connect to.
InetAddress addr = null;
try {
addr = InetAddress.getByName(INET_ADDR);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Open a new DatagramSocket, which will be used to send the data.
try (DatagramSocket serverSocket = new DatagramSocket()) {
msg += "\\0";
for (int i = 0; i < 10; i++) {
// Create a packet that will contain the data
// (in the form of bytes) and send it.
DatagramPacket msgPacket = new DatagramPacket(msg.getBytes(),
msg.getBytes().length, addr, PORT);
serverSocket.send(msgPacket);
System.out.println("Server sent packet with msg: " + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
serverSocket.disconnect();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Client Class:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.TimerTask;
public class MulticastSocketClient implements Runnable {
final static String INET_ADDR = "224.0.0.3";
final static int PORT = 8888;
Connection360 conn;
public MulticastSocketClient (Connection360 connection) throws UnknownHostException {
conn = connection;
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
try{
// Get the address that we are going to connect to.
InetAddress address = InetAddress.getByName(INET_ADDR);
// Create a buffer of bytes, which will be used to store
// the incoming bytes containing the information from the server.
// Since the message is small here, 256 bytes should be enough.
byte[] buf = new byte[256];
// Create a new Multicast socket (that will allow other sockets/programs
// to join it as well.
try (final MulticastSocket clientSocket = new MulticastSocket(PORT)){
//Joint the Multicast group.
clientSocket.joinGroup(address);
System.out.println("Connected");
//while (true) {
// Receive the information and print it.
DatagramPacket msgPacket = new DatagramPacket(buf, buf.length);
Timer timer = new Timer("tmr");
timer.schedule(new TimerTask() {
#Override
public void run() {
clientSocket.disconnect();
}
},10000);
clientSocket.receive(msgPacket);
String msg = new String(buf, 0, buf.length);
System.out.println("Socket 1 received msg: " + msg.substring(0, msg.indexOf("\\0")));
conn.MessageReceived(msg.substring(0, msg.indexOf("\\0")));
clientSocket.disconnect();
//}
} catch (IOException ex) {
ex.printStackTrace();
}
}catch (UnknownHostException ex){
}
}
}
This classes are the ones I made for the desktop app. The classes I made for the Android app are the same, but I had to change the System.out.println() to Log.v(). As for the rest, it's exactly the same.
So, if you happen to know what could be happening, I would really appreciate your assistance with the topic.
Thank you!
When you read the incoming packet, you don't use its size but the size of the buffer instead:
String msg = new String(buf, 0, buf.length);
// should be:
String msg = new String(buf, 0, msgPacket.getLength());
// or even better:
String msg = new String(msgPacket.getData());
If the incoming packet is shorter, the rest of the buffer contains random data which is what you got. Java strings are not NUL-terminated so msg.indexOf("\\0") does not work.

Trying to get a java socket program to work, but getting "java.net.BindException: Address already in use 6666 "

Here is the code
I have written a server and client. But when i run them, (as you can see in the last program), I get the following error:
Whoop s! java.net.BindException: Address already in use 6666
6666 is the port no. i specified.
import java.net.*;
import java.io.*;
import java.lang.*;
public class processSendHelper
{
Process p;
String address;
int port;
long msg_data;
processSendHelper(int pid, int current_round, long address, long msg_data, int port)
{
try
{
ServerSocket sSoc = new ServerSocket(port);
Socket inSoc = sSoc.accept();
msg_Thread msgT = new msg_Thread(inSoc, msg_data);
msgT.start();
Thread.sleep(5000);
sSoc.close();
}
catch(Exception e)
{
System.out.println("Whoop s! " + e.toString());
}
}
}
/* sends out (or rather just makes available) the provided msg
* */
class msg_Thread extends Thread
{
Socket threadSoc;
long msg_data;
msg_Thread (Socket inSoc, long msg_data)
{
threadSoc = inSoc;
this.msg_data = msg_data;
}
public void run()
{
try
{
PrintStream SocOut = new
PrintStream(threadSoc.getOutputStream());
SocOut.println(msg_data);
}
catch (Exception e)
{
System.out.println("Whoops!" + e.toString());
}
try
{
threadSoc.close();
}
catch (Exception e)
{
System.out.println("Oh no! " +
e.toString());
}
}
}
import java.net.*;
import java.io.*;
public class processReceiveHelper
{
Socket appSoc;
BufferedReader in;
String message;
String host;
int port;
processReceiveHelper(String host,int port)
{
try
{
appSoc = new Socket(host,port);
in = new BufferedReader(new InputStreamReader(appSoc.getInputStream()));
message = in.readLine();
System.out.println(message);
/* Tokenizer code comes here
* Alongwith the code for
* updating the process object's
* data
* */
}
catch (Exception e)
{
System.out.println("Died... " +
e.toString());
}
}
}
public class Orchestrator
{
public static void main(String[] args)
{
processSendHelper psh = new processSendHelper(1, 2, 1237644, 6666, 2002);
processReceiveHelper prh = new processReceiveHelper("localhost", 2002);
}
}
EDIT:
I found the problem. The reason was that i was running both the server and client from the same main program.
the following worked:
That means there is already an application operating on port 6666 preventing your Java application using it. However, it is equally possible there is a running process of your Java application still holding onto 6666. Terminate any running java processes and try re-running the code - if it still fails then you have some other application using 6666 and you would be better using a different port.
That means that the port 6666 is already being used. There are two main causes/solutions for this:
Some other program is using that port. Solution: Choose a different port.
Your old Java program is hanging and still "using" that port. Close all of your hanging Java programs and try again. If that doesn't solve your problem, choose a different port.
Does it happen when you run the program for the second time? You may want to setReuseAddress(true) on this socket.

Categories