I have a server that will be running on another machine and I need to debug with two different machines. Is there a way to virtually debug the server since everything runs ok on my machine but when i put it on another machine everything wrong? I dont have another machine in my possession (I can only host and see results) .
public class fss { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; boolean listening = true; boolean allowed = true; // int port = Integer.parseInt(args[0]); int port
= 60000;
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Could not transmit on port: " + port);
System.exit(-1);
}
while (listening) {
//Take the ip of the client in number form
allowed = true;
Socket socket = serverSocket.accept();
DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
String clientAddress = socket.getRemoteSocketAddress().toString();
clientAddress = clientAddress.substring(1);
for (int i = 0; i < clientAddress.length() - 1; i++) {
if (clientAddress.substring(i, i + 1).equals(":")) {
clientAddress = clientAddress.substring(0, i);
}
}
File f = new File("forbidden.txt");
if (f.exists()) {
BufferedReader forbidden = new BufferedReader(new FileReader("forbidden.txt"));
String addr;
while ((addr = forbidden.readLine()) != null) {
if (Character.isLetter(addr.charAt(0))) {//if the address is in a letter form
addr = InetAddress.getByName(addr).toString();
for (int i = 0; i < addr.length() - 1; i++) {
//System.out.println(addr.substring(i, i + 1));
if (addr.substring(i, i + 1).equals("/")) {
addr = addr.substring(i + 1);
}
}
}
if (clientAddress.equals(addr)) {
allowed = false;
break;
}
}
if (allowed == true) {
new MultiThread(socket).start();
} else {
outToClient.writeBytes("Connection refused" + "\n");
socket.close();
forbidden.close();
}
} else {
new MultiThread(socket).start();
}
}
serverSocket.close();
}
}
You will have to enable debug on server JVM.
This is typically done via following JVM args -
-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8787
You then need to connect to the process using server's IP Address and the above debug port - 8787
One of the answers has already indicated how to enable JDWP on the server. This would require that you have appropriate permissions to open the necessary port as well.
If you do not have this permission, I would humbly suggest using a logger. Your code is completely bereft of any logging calls that would have aided in a scenario where you do not have a lot of control over the runtime environment.
You could start with using the logging framework within Java - java.util.logging, but you'll find log4j or slf4j to be more intuitive.
Related
I try to make my own proxy server and already implemented the http support for my proxy server. The proxy server works fine.
Now I want to have https as well (only with sockets). I looked up what I have to do at https://www.rfc-editor.org/rfc/rfc2817.
In my function I try to establish a TLS tunnel.
With my approach I only get a method not allowed as response. I also check some source in the internet, but didn't find anything which can help me with my problem.
Here is my function.
private Socket openTLSTunnel(String host) throws IOException {
String raw_request = "CONNECT " + host + ":80 HTTP/1.1\n"
+ "Host: " + host + ":80"
+ "\r\n\r\n";
// Make a connection to the website.
Socket tunnel = new Socket();
int timeout = 10000;
var server = new InetSocketAddress(host, 80);
tunnel.connect(server, timeout);
// Write the request to server.
OutputStream out = tunnel.getOutputStream();
byte[] msg = raw_request.getBytes(StandardCharsets.UTF_8);
out.write(msg);
out.flush();
// TODO send error to client.
// Get the response from server.
InputStream in = tunnel.getInputStream();
byte reply[] = new byte[200];
int replyLen = 0;
int newlinesSeen = 0;
boolean headerDone = false;
while (newlinesSeen < 2) {
int i = in.read();
if (i < 0) {
throw new IOException("Unexpected EOF from proxy");
}
if (i == '\n') {
headerDone = true;
++newlinesSeen;
}
else if (i != '\r') {
newlinesSeen = 0;
if (!headerDone && replyLen < reply.length) {
reply[replyLen++] = (byte) i;
}
}
}
String replyStr = new String(reply, 0, replyLen, "ASCII7");
// Check if connection established.
if(!replyStr.toLowerCase().contains("200 connection established")) {
System.out.println("No TLS connection established!");
throw new AccessDeniedException(replyStr);
}
else{
System.out.println("Connection established!");
}
return tunnel;
}
Thanks in advance!
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
So I'm trying to create an smtp from scratch, (assignment) and I'm trying to connect classes together but miserably failing and trying everything out. The compiler doesn't throw up any errors but when I run it I don't get very far. I tried calling the other classes with the .start thread but still, failure
If you could help me or give tips, I would really appreciate it
//Problem seems to be here: I have no idea how to correct it
socketManager soketManager = null;
DataInputStream clientDataIn = new DataInputStream(soketManager.getInputStream());
socketManager clientReaderSocket = soketManager;```
public class socketManager {
public Socket soc = null;`
`
//socketManager.java
public DataInputStream input = null;
public DataOutputStream output = null;
public socketManager(Socket socket) throws IOException {
soc = socket;
input = new DataInputStream(soc.getInputStream());
output = new DataOutputStream(soc.getOutputStream());
}
public InputStream getInputStream() throws IOException {
input = new DataInputStream(soc.getInputStream());
return null;
}
public OutputStream getOutputStream() throws IOException {
output = new DataOutputStream(soc.getOutputStream());
return null;
}
}
Exception in thread "Thread-1" java.lang.NullPointerException at
me.censored.loopback.SMTPclient.Client$ClientSocketManager.run(Client.java:117)
at java.base/java.lang.Thread.run(Thread.java:834)
// Main Method:- called when running the class file.
public static void main(String[] args) throws UnknownHostException, IOException {
Port Declaration & Checks.
String serverIP = "loopback";
int defaultServerPort = 25;
PortManager portManage = new PortManager();
Thread portManagerThread = new Thread(portManage);
portManagerThread.start();
}// End of main
static public class PortManager implements Runnable {
Scanner userInput = new Scanner(System.in);
int serverPort = 25;
// Will accept only tcp/udp ports as of (2019) After several attempts the port
// will be auto selected to default 25,
// Should we accept parsed HEX?
boolean portCompletion = false;
short portTriesCounter = 1;
public void run() {
try {
do {
// Asks user for server's port at the start up of the client.
System.out.println("Please enter the port the server is on.");
String userEntry = userInput.nextLine();
userInput.close();
try {
serverPort = Integer.parseInt(userEntry);
if (portTriesCounter != 5) { // Partial tries timeout.
if (serverPort != 0) { // "Port Zero" does not officially exist. It is defined as an invalid
// port
// number. But valid Internet packets can be formed and sent "over
// the
// wire"
// to and from "port 0" just as with any other ports.
if ((serverPort > 0 && serverPort <= 1023)
|| (serverPort >= 1024 && serverPort <= 49151)
|| (serverPort >= 49152 && serverPort <= 65535)) // Check for ports inside the
// tcp/udp
// range
portCompletion = true;
else {
System.out.println(
"Wrong input! Make sure you are using correct numbers and port range! ");
portCompletion = false;
portTriesCounter++;
}
// End Check for ports inside the tcp/udp range
} else {
System.out.print("Wrong input! ");
portCompletion = false;
portTriesCounter++;
}
// End Check for zero
}
// End Too many attempts
else {
portTriesCounter = 5;
portCompletion = true;
System.out.print("Many wrong attemps. Selecting and trying the default port (25)... ");
try {
System.out.print("Success");
portCompletion = true;
serverPort = 25; // For SSL connections use port 465.
} catch (Exception except) {
portCompletion = false;
}
}
} catch (Exception except) {
portCompletion = false;
portTriesCounter++;
} finally {
userInput.close();
}
} while (!portCompletion);
ClientSocketManager clientSocketManage = new ClientSocketManager();
Thread clientSocketManagerThread = new Thread(clientSocketManage);
clientSocketManagerThread.start();
System.out.println("DEBUG 0");
} catch (Exception except) { // Any Failure will send 421 Error to client
System.out.println("\t 421 \t Service not available, closing transmission channel.\n" + except);
}
}
}
static class ClientSocketManager implements Runnable {
public void run() {
try {
String CRLF = "\r\n";
String LF = "\n";
boolean SocketInitiation = false;
socketManager soketManager = null;
DataInputStream clientDataIn = new DataInputStream(soketManager.getInputStream());
socketManager clientReaderSocket = soketManager;
DataOutputStream clientDataOut;
clientDataOut = new DataOutputStream(soketManager.getOutputStream());
String sendSocketMessage = (CRLF);
clientDataOut.writeUTF(sendSocketMessage);// Sends string to output stream using UTF-8
clientDataOut.flush();
System.out.println("DEBUG 1");
String socketReplyIn = clientDataIn.readUTF();
PortManager portInstance = new PortManager();
int portNumber = portInstance.serverPort;
Socket soket = new Socket("loopback", portNumber);
ClientWriter clientWrite = new ClientWriter(soket);
Thread clientWriteThread = new Thread(clientWrite);
ClientReader clientRead = new ClientReader(soket);
Thread clientReadThread = new Thread(clientRead);
System.out.println("DEBUG 2");
// Cleans stream from any write buffer method.
System.out.println("Connection to server using TCP...");
if (socketReplyIn.contains("220")) {
System.out.println("\t 220 \t Service ready"); // Connection established successfully
clientReadThread.start();
clientWriteThread.start();
SocketInitiation = true;
} else {
System.out.println("\t 421 \t Service not available, closing transmission channel");
SocketInitiation = false;
}
} catch (IOException e) {
System.out.println("\t 421 \t Service not available, closing transmission channel");
System.out.println("TCP connection error: " + e);
}
}
}
you have defined socketManager soketManager = null; in ClientSocketManager.
but you never assigned a value to it, so it is still null.
The code after that is trying to access streams from it, which is throwing NullPointerException:
DataInputStream clientDataIn = new DataInputStream(soketManager.getInputStream());
socketManager clientReaderSocket = soketManager;
DataOutputStream clientDataOut;
clientDataOut = new DataOutputStream(soketManager.getOutputStream());
String sendSocketMessage = (CRLF);
clientDataOut.writeUTF(sendSocketMessage);// Sends string to output stream using UTF-8
clientDataOut.flush();
System.out.println("DEBUG 1");
just create a new instance of the socketManager and assign it to soketManager before using it.
PortManager portInstance = new PortManager();
int portNumber = portInstance.serverPort;
Socket soket = new Socket("loopback", portNumber);
socketManager soketManager = new sockerManager(soket);
This question already has answers here:
Setting a timeout for socket operations
(6 answers)
Closed 7 years ago.
There are 2 backend machines which will provide the same content. I'm trying to create a round-robin setup and fail-safe so that if one goes down, the request should be sent to other.
As for the round-robin thing, my code is working fine.
For the fail-safe thing, I'm trying to change one IP to some invalid ip (on which no service is running) and then it should connect to other. But it is getting hung up on the line:
client = new Socket(ip, port);
What can be done for this? If I'm not getting connection in 2 seconds, I don't want to retry (if that is what java does, can I reduce the retry timeout?).
Also, after long time, it throws IllegalStateException (I was not expecting it at all)
Here is my constructor for Connect.java:
//Variable declartion
private static int balancer = 0;
private static boolean[] down = {false, false};
private static int[] countDown = {0, 0};
private static final int maxRequests = 10000;
private static int countRequests = 0;
//Constructor
public Connect() throws NullPointerException{
int use = balancer;
int flag = 0;
countRequests = (countRequests + 1) % maxRequests;
if(countRequests == 0){
down[0] = down[1] = false;
}
if((balancer == 0 && down[0] == false) || down[1] == true){
ip = Config.IP1;
port = Config.PORT1;
use = 0;
System.out.println("balancer = 0");
}
else{
ip = Config.IP2;
port = Config.PORT2;
use = 1;
System.out.println("balancer = 1");
}
LOGGER.setLevel(Level.INFO);
// Single simple socket
try {
client = new Socket(ip, port);
System.out.println("client");
dos = new DataOutputStream(client.getOutputStream());
dis = new DataInputStream(client.getInputStream());
if(client == null || dos == null || dis == null){
throw new IOException("Connection could not be opened properly\n");
}
LOGGER.log(Level.INFO, "Connection to : " + ip + " Successfully opened");
balancer = (balancer == 0) ? 1 : 0;
countDown[use] = 0;
flag = 1;
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
countDown[use] ++;
if(countDown[use] >= 3){
down[use] = true;
}
LOGGER.log(Level.SEVERE, ": " + ip + " " + e.getMessage());
}
finally{ //if connection was not opened on first
if(flag == 0){
if(use == 0){
ip = Config.IP2;
port = Config.PORT2;
use = 1;
}
else{
ip = Config.IP1;
port = Config.PORT1;
use = 0;
}
try {
client = new Socket(ip, port);
dos = new DataOutputStream(client.getOutputStream());
dis = new DataInputStream(client.getInputStream());
if(client == null || dos == null || dis == null){
throw new IOException("Connection could not be opened properly\n");
}
LOGGER.log(Level.INFO, "Connection to " + ip + " Successfully opened");
balancer = (balancer == 0) ? 1 : 0;
countDown[use] = 0;
flag = 1;
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
countDown[use] ++;
if(countDown[use] >= 3){
down[use] = true;
}
LOGGER.log(Level.SEVERE, ": " + ip + " " + e.getMessage());
throw new NullPointerException("Connection could not be opened properly on both machines\n");
}
}
}
}
What I expected was an IO/NullPointer-Exception and then catch block will be executed
How about using the default Socket() constructor, and then connect(SocketAddress, int), which allows you to specify a specific timeout?
Example:
import java.net.*;
public class Test {
public static void main(String[] args) throws Exception {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(args[0], 80), 2000);
}
}
You can see the timeout in action by timing it:
$ time java Test google.com
real 0m0.154s
user 0m0.079s
sys 0m0.022s
$ time java Test 192.168.2.123
Exception in thread "main" java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at Test.main(Test.java:5)
real 0m2.111s
user 0m0.076s
sys 0m0.026s
So, I guess that this has been answered before, but I couldn't find the question, so forgive me.
I have a rather basic chat client-server pair, of which the server is multithreaded to allow for several clients to connect at the same time. The server code looks like this...
private void loop(int port) {
// Opens a port for connections.
ServerSocket serverSocket = null;
Socket clientSocket = new Socket();
try {
serverSocket = new ServerSocket(port);
System.out.println("Server running in port " + port);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// Listens for a connection
while (onlineState == true && serverSocket != null) {
if (cur_players < max_players) {
try {
clientSocket = serverSocket.accept();
System.out.println(clientSocket.getInetAddress() + " has connected to the port " + clientSocket.getPort());
cur_players++;
new Thread(new SocketThread( clientSocket, Chat.getOpenSeat() )).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Here, what Chat.getOpenSeat() does is browse an array(boolean seats[]) through for an open spot in the chat buffer array (String buffer[][]) and returns an integer for the spot, then marking it taken. However, when I access the buffer array from the threads, the thread only finds the messages it has added itself. Below is the corresponding code.
toClient = c.poll(bufferSocket); // Retrieves the top-most message from the seat's sub-array,
// then bumps the remaining messages up in the sub-array.
if (toClient != null) {
out.println(toClient); // Sends the message through the Socket.
System.out.println("Message was sent.");
toClient = null;
}
Curiously enough, the threads can access the seats[] array without any trouble, finding the currently active seats and correctly giving all the corresponding sub-arrays their messages. Here's also the bit of code I use to add a new message to the array:
public void offer(String msg) {
for (int seat = 0; seat < Server.max_players; seat++) {
if (seats[seat] == true) {
for (int i = 0; i < 100; i++) {
if (msgBuffer[seat][i] == null) {
msgBuffer[seat][i] = msg;
System.out.println("Message: '" + msg + "' was buffered for the Seat " + seat + ".");
break;
}
}
}
}
}
So, how do I add Strings to an array that is commonly read-write accessible to all of my threads?
Just ask if you need to see more of the code.
Make the array volatile, and it will behave concurrent.
More on volatile: http://www.javamex.com/tutorials/synchronization_volatile.shtml.
This question already has answers here:
Java detect lost connection [duplicate]
(9 answers)
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 9 years ago.
I have a java program with Socket. I need to check if client has disconnected. I need a example how to do that. I have researched but I don't understand. So can someone make example code and explane everything.
sorry for bad English
my code:
package proov_server;
//SERVER 2
import java.io.*;
import java.net.*;
class server2 {
InetAddress[] kasutaja_aadress = new InetAddress[1000];
String newLine = System.getProperty("line.separator");
int kliendiNr = 0;
int kilene_kokku;
server2(int port) {
try {
ServerSocket severi_pistik = new ServerSocket(port);
System.out.println("Server töötab ja kuulab porti " + port + ".");
while (true) {
Socket pistik = severi_pistik.accept();
kliendiNr++;
kasutaja_aadress[kliendiNr] = pistik.getInetAddress();
System.out.println(newLine+"Klient " + kliendiNr + " masinast "
+ kasutaja_aadress[kliendiNr].getHostName() + " (IP:"
+ kasutaja_aadress[kliendiNr].getHostAddress() + ")");
// uue kliendi lõime loomine
KliendiLoim klient = new KliendiLoim(pistik,kliendiNr);
// kliendi lõime käivitamine
klient.start();
}
}
catch (Exception e) {
System.out.println("Serveri erind: " + e);
}
}
DataOutputStream[] väljund = new DataOutputStream[1000];
DataInputStream[] sisend = new DataInputStream[1000];
int klient = 0;
int nr;
// sisemine klass ühendusega tegelemiseks
class KliendiLoim extends Thread {
// kliendi pistik
Socket pistik;
// kliendi number
KliendiLoim(Socket pistik2,int kliendiNr) {
nr = kliendiNr;
this.pistik = pistik2;
}
public boolean kontroll(){
try{
System.out.println("con "+pistik.isConnected());
System.out.println("close "+pistik.isClosed());
if(pistik.isConnected() && !pistik.isClosed()){
//System.out.print(con_klient);
return true;
}
}catch(NullPointerException a){
System.out.println("Sihukest klienti pole!!!");
}
kliendiNr --;
return false;
}
public void run() {
try {
sisend[nr] = new DataInputStream(pistik.getInputStream()); //sisend
väljund[nr] = new DataOutputStream(pistik.getOutputStream()); //väljund
}catch (Exception ea) {
System.out.println(" Tekkis erind: " + ea);
}
while(true){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Sisesta k2sk: ");
String k2sk = null;
k2sk = br.readLine();
/*
String command;
if(k2sk.indexOf(" ") < 0){
command = k2sk;
}else{
command = k2sk.substring(0, k2sk.indexOf(" "));
}
*/
String[] words = k2sk.split("\\s+");
for (int i = 0; i < words.length; i++) {
words[i] = words[i].replaceAll(" ", "");
}
switch(words[0]){
case "suhtle":
if(väljund.length > klient && väljund[klient] != null)
{
väljund[klient].writeUTF("1");
}else{
väljund[klient] = null;
sisend[klient] = null;
System.out.println("Sihukest klienti pole");
}
break;
case "vaheta":
try{
int klinetnr = Integer.parseInt(words[1]);
//if(kontroll(klinetnr) ){
klient = Integer.parseInt(words[1]);
//}
}
catch(NumberFormatException e){
System.out.println("See pole number!!! ");
}
break;
case "kliendid":
if(kliendiNr != 0){
for(int i=1;i <= kliendiNr;i++){
if(kontroll()){
System.out.println("Klient:"+i+" ip: " + kasutaja_aadress[i] );
}else{
System.out.println("Pisi");
väljund[klient] = null;
sisend[klient] = null;
}
}
System.out.println(newLine);
}else{
System.out.println("Kiente pole");
}
break;
}
System.out.println(kliendiNr);
}catch(SocketException a){
System.out.println("Klient kadus");
}
catch(Exception e){
System.out.println(" Viga: " + e);
}
}
}
}
public static void main(String[] args) {
new server2(4321);
}
}
If the client has disconnected properly:
read() will return -1
readLine() returns null
readXXX() for any other X throws EOFException.
The only really reliable way to detect a lost TCP connection is to write to it. Eventually this will throw an IOException: connection reset, but it takes at least two writes due to buffering.
A related thread on Stackoverflow here along with the solution. Basically, the solution says that the best way to detect a client-server disconnect is to attempt to read from the socket. If the read is successfully, then the connection is active.If an exception is thrown during the read there is no connection between the client and the server. Alternatively it may happen that the socket is configured with a timeout value for the read operation to complete. In case, this timeout is exceeded a socket timeout exception will be thrown which can be considered as either the client is disconnected or the network is down.
The post also talks about using the isReachable method - refer InetAddress documentation. However, this method only tells us whether a remote host is reachable or not. This may just one of the reasons for the client to disconnect from the server. You wont be able to detect disconnection due to client crash or termination using this technique.