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);
Related
I am coding client-server multithread calculator using java, socket programming.
There's any syntax error, but msgs cannot be received from server.
I think
receiveString = inFromServer.readLine()
does not works. This code is in Client program, in the while(true) loop.
What is the problem?
Here is my full code.
SERVER
import java.io.*;
import java.net.*;
public class Server implements Runnable
{
static int max = 5; //maximum thread's number
static int i = 0, count = 0; //i for for-loop, count for count number of threads
public static void main(String args[]) throws IOException
{
ServerSocket serverSocket = new ServerSocket(6789); //open new socket
File file = new File("src/serverinfo.dat"); //make data file to save server info.
System.out.println("Maximum 5 users can be supported.\nWaiting...");
for(i=0; i <= max; i++) { new Connection(serverSocket); } //make sockets - loop for max(=5) times
try //server information file writing
{
String dataString = "Max thread = 5\nServer IP = 127.0.0.1\nServer socket = 6789\n";
#SuppressWarnings("resource")
FileWriter dataFile = new FileWriter(file);
dataFile.write(dataString);
}
catch(FileNotFoundException e) { e.printStackTrace(); }
catch(IOException e) { e.printStackTrace(); }
}
static class Connection extends Thread
{
private ServerSocket serverSocket;
public Connection(ServerSocket serverSock)
{
this.serverSocket = serverSock;
start();
}
public void run()
{
Socket acceptSocket = null;
BufferedReader inFromClient = null;
DataOutputStream msgToClient = null;
String receiveString = null;
String result = "", sys_msg = "";
try
{
while(true)
{
acceptSocket = serverSocket.accept(); // 접속수락 소켓
count++;
inFromClient = new BufferedReader(new InputStreamReader(acceptSocket.getInputStream()));
msgToClient = new DataOutputStream(acceptSocket.getOutputStream());
System.out.println(count + "th client connected: " + acceptSocket.getInetAddress().getHostName() + " " + count + "/" + max);
System.out.println("Waiting response...");
while(true)
{
if (count >= max+1) // if 6th client tries to access
{
System.out.println("Server is too busy. " + max + " clients are already connected. Client access denied.");
sys_msg = "DENIED";
msgToClient.writeBytes(sys_msg);
acceptSocket.close();
count--;
break;
}
try{ msgToClient.writeBytes(result); }
catch(Exception e) {}
try{ receiveString = inFromClient.readLine(); }
catch(Exception e) // if receiveString = null
{
System.out.println("Connection Close");
count--;
break;
}
System.out.println("Input from client : " + receiveString);
try
{
if(receiveString.indexOf("+") != -1) { result = cal("+", receiveString); }
else if(receiveString.indexOf("-") != -1) { result = cal("-", receiveString); }
else if(receiveString.indexOf("/") != -1) { result = cal("/", receiveString); }
else if(receiveString.indexOf("*") != -1) { result = cal("*", receiveString); }
else if(receiveString.indexOf("+") == -1 || receiveString.indexOf("-") == -1 || receiveString.indexOf("*") == -1 || receiveString.indexOf("/") == -1) { result = "No INPUT or Invalid operation"; }
}
catch(Exception e){ result = "Wrong INPUT"; }
try{ msgToClient.writeBytes(result); }
catch(Exception e) {}
}
}
}
catch(IOException e) { e.printStackTrace(); }
}
}
private static String cal(String op, String recv) //function for calculating
{
double digit1, digit2; //first number, second number
String result = null;
digit1 = Integer.parseInt(recv.substring(0, recv.indexOf(op)).trim());
digit2 = Integer.parseInt(recv.substring(recv.indexOf(op)+1, recv.length()).trim());
if(op.equals("+")) { result = digit1 + " + " + digit2 + " = " + (digit1 + digit2); }
else if(op.equals("-")) { result = digit1 + " - " + digit2 + " = " + (digit1 - digit2); }
else if(op.equals("*")) { result = digit1 + " * " + digit2 + " = " + (digit1 * digit2); }
else if(op.equals("/"))
{
if(digit2 == 0){ result = "ERROR OCCURRED: Cannot be divided by ZERO"; }
else{ result = digit1 + " / " + digit2 + " = " + (digit1 / digit2); }
}
return result;
}
#Override
public void run() {
// TODO Auto-generated method stub
}
}
-----------------------------------------------------------------
CLIENT
import java.io.*;
import java.net.*;
public class Client {
public static void main(String args[]) throws IOException
{
Socket clientSocket = null;
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
BufferedReader inFromServer = null;
DataOutputStream msgToServer = null;
String sendString = "", receiveString = "";
try
{
clientSocket = new Socket("127.0.0.1", 6789); //make new clientSocket
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
msgToServer = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("Input exit to terminate");
System.out.println("Connection Success... Waiting for permission");
while(true)
{
receiveString = inFromServer.readLine();
if(receiveString.equals("DENIED"))
{
System.out.println("Server is full. Try again later.");
break;
}
else { System.out.println("Connection permitted."); }
System.out.print("Input an expression to calculate(ex. 3+1): ");
sendString = userInput.readLine();
if(sendString.equalsIgnoreCase("exit")) //when user input is "exit" -> terminate
{
clientSocket.close();
System.out.println("Program terminated.");
break;
}
try { msgToServer.writeBytes(sendString); }
catch(Exception e) {}
try { receiveString = userInput.readLine(); }
catch(Exception e) {}
System.out.println("Result: " + receiveString); //print result
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
You've set up your server socket stack wrong.
Your code will make 5 threads, each calling accept on a serversocket.
The idea is to have a single ServerSocket (and not 5, as in your example). Then, this single serversocket (running in a single thread that handles incoming sockets flowing out of this serversocket) will call .accept which will block (freeze the thread) until a connection is made, and will then return a Socket object. You'd then spin off a thread to handle the socket object, and go right back to the accept call. If you want to 'pool' (which is not a bad idea), then disassociate the notion of 'handles connections' from 'extends Thread'. For example, implement Runnable instead. Then pre-create the entire pool (for example, 10 threads), have some code that lets you 'grab a thread' from the pool and 'return a thread' to the pool, and now the serversocket thread will, upon accept returning a socket object, grab a thread from the pool (which will block, thus also blocking any incoming clients, if every thread in the pool is already taken out and busy handling a connection), until a thread returns to the pool. Alternatively, the serversocket code checks if the pool is completely drained and if so, will put on a final thread the job of responding to that client 'no can do, we are full right now'.
I'm not sure if you actually want that; just.. make 1 thread per incoming socket is a lot simpler. I wouldn't dive into pool concepts until you really need them, and if you do, I'd look for libraries that help manage them. I think further advice on that goes beyond the scope of this question, so I'll leave the first paragraph as an outlay of how ServerSocket code ought to work, for context.
I am working on my assignment to make UDP reliable using java. How can i add Timeout and re-transmission to handle data-grams that are discarded and add Sequence numbers so the client can verify that a reply is for the appropriate request ??
this is client code
import java.net.*;
import java.io.*;
public class EchoClient {
// UDP port to which service is bound
public static final int SERVICE_PORT = 7;
// Max size of packet
public static final int BUFSIZE = 256;
public static void main(String args[]){
if (args.length != 1)
{
System.err.println ("Syntax - java EchoClient hostname");
return;
}
String hostname = args[0];
// Get an InetAddress for the specified hostname
InetAddress addr = null;
try
{
// Resolve the hostname to an InetAddr
addr = InetAddress.getByName(hostname);
}
catch (UnknownHostException uhe)
{
System.err.println ("Unable to resolve host");
return;
}
try
{
// Bind to any free port
DatagramSocket socket = new DatagramSocket();
// Set a timeout value of two seconds
socket.setSoTimeout (2 * 1000);
for (int i = 1 ; i <= 10; i++)
{
// Copy some data to our packet
String message = "Packet number " + i ;
char[] cArray = message.toCharArray();
byte[] sendbuf = new byte[cArray.length];
for (int offset = 0; offset < cArray.length ; offset++)
{
sendbuf[offset] = (byte) cArray[offset];
}
// Create a packet to send to the UDP server
DatagramPacket sendPacket = new DatagramPacket(sendbuf, cArray.length, addr, SERVICE_PORT);
System.out.println ("Sending packet to " + hostname);
// Send the packet
socket.send (sendPacket);
System.out.print ("Waiting for packet.... ");
// Create a small packet for receiving UDP packets
byte[] recbuf = new byte[BUFSIZE];
DatagramPacket receivePacket = new DatagramPacket(recbuf, BUFSIZE);
// Declare a timeout flag
boolean timeout = false;
// Catch any InterruptedIOException that is thrown
// while waiting to receive a UDP packet
try
{
socket.receive (receivePacket);
}
catch (InterruptedIOException ioe)
{
timeout = true;
}
if (!timeout)
{
System.out.println ("packet received!");
System.out.println ("Details : " + receivePacket.getAddress() );
// Obtain a byte input stream to read the UDP packet
ByteArrayInputStream bin = new ByteArrayInputStream (
receivePacket.getData(), 0, receivePacket.getLength() );
// Connect a reader for easier access
BufferedReader reader = new BufferedReader (
new InputStreamReader ( bin ) );
// Loop indefinitely
for (;;)
{
String line = reader.readLine();
// Check for end of data
if (line == null)
break;
else
System.out.println (line);
}
}
else
{
System.out.println ("packet lost!");
}
// Sleep for a second, to allow user to see packet
try
{
Thread.sleep(1000);
}catch (InterruptedException ie) {}
}
}
catch (IOException ioe)
{
System.err.println ("Socket error " + ioe);
}
}
}
What you can do is adding import TCP headers like sequence number, windows into the UDP message body to make it more like TCP. Here is the a solution that might help you.
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
Hey Guys my following code is a proxy written in java.
Everytime I try to run it, it throws an String Index out of range:-1 exception, which I don't know how to handle.
I also nee to redirect the request to a specific webpage, if a "bad" word has been written in the URL or the content of the web page.
How do I do that?
Please Help me!
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class ProxyServer{
//Create the Port the user wants the proxy to be on
static Scanner sc = new Scanner(System.in);
public static final int portNumber = sc.nextInt();
public static void main(String[] args) {
ProxyServer proxyServer = new ProxyServer();
proxyServer.start();
}
public void start() {
System.out.println("Starting the SimpleProxyServer ...");
try {
//bad list of words
String bad[]= new String[4];
bad[0]= "SpongeBob";
bad[1]= "Britney Spears";
bad[2]= "Norrköping";
bad[3]= "Paris Hilton";
ServerSocket serverSocket = new ServerSocket(ProxyServer.portNumber);// this is the socket of the proxy
System.out.println(serverSocket);
byte[] buffer= new byte [10000] ;
//
while (true) {
Socket clientSocket = serverSocket.accept(); // the client willl be the socket the proxy "accepts"
boolean badContent =false; //flag, if the input contains one of the bad words
InputStream inputstream = clientSocket.getInputStream(); // retreiving request from the client
int n = inputstream.read(buffer); //reading buffer and storing its size
String browserRequest= new String(buffer,0,n+1); //new String(buffer,0,n);
String realbrowserRequest =( browserRequest+"Connection close()");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputstream));
for (int j=0; j<bad.length;j++){ //checking of the URL contains the bad words
if(realbrowserRequest.contains(bad[j])){
badContent =true; // if yes the flag will be set to true
}
}
//if(badContent == true){
//System.out.println("bad detected");
// try
// {
// URL url = new URL( "http://www.ida.liu.se/~TDTS04/labs/2011/ass2/error2.html" );
//
// BufferedReader in = new BufferedReader(
// new InputStreamReader( url.openStream() ) );
//
// String s;
//
// while ( ( s = in.readLine() ) != null )
// System.out.println( s );
//
// in.close();
// }
// catch ( MalformedURLException e ) {
// System.out.println( "MalformedURLException: " + e );
// }
// catch ( IOException e ) {
// System.out.println( "IOException: " + e );
// }
// else{
System.out.println("Das ist der Browserrequest: \n"+realbrowserRequest);
System.out.println("Das ist der Erste Abschnitt");
int start = browserRequest.indexOf(("Host: ") + 6);
int end = browserRequest.indexOf('\n', start);
String host = browserRequest.substring(start, end-1 ); //retreiving host
if(badContent =true) //if the URL already contains inappropriate material
{
URL url = new URL( "http://www.ida.liu.se/~TDTS04/labs/2011/ass2/error2.html" );
host = url.getHost(); // set the host to the given one
}
System.out.println("Connecting to host " + host);
Socket hostSocket = new Socket(host, 80); //I can change the host over here
OutputStream HostOutputStream = hostSocket.getOutputStream();
// PrintWriter writer= new PrintWriter (HostOutputStream);
// writer.println();
System.out.println("Forwarding request to server");
HostOutputStream.write(buffer, 0, n);// but then the buffer that is fetched from the client remains same
HostOutputStream.flush();
InputStream HostInputstream = hostSocket.getInputStream();
OutputStream ClientGetOutput = clientSocket.getOutputStream();
System.out.println("Forwarding request from server");
do {
n = HostInputstream.read(buffer);
String vomHost = new String(buffer,0,n);
System.out.println("\nVom Host\n\n"+vomHost);
for(int i=0;i<bad.length;i++){
if(vomHost.contains(bad[i])){
badContent=true;
}
}
System.out.println("Receiving " + n + " bytes");
if (n > 0) { // && badContent == false
ClientGetOutput.write(buffer, 0, n);
}
} while (n>0 && badContent == false); //n>0&& badContent == false
if (badContent == true){
}
ClientGetOutput.flush();
hostSocket.close();
clientSocket.close();
System.out.println("End of communication");
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
The issue is here :
int start = browserRequest.indexOf(("Host: ") + 6);
This means you are doing this :
int start = browserRequest.indexOf("Host: 6");
6 is being concatenated to "Host : "
Try this :
int start = browserRequest.indexOf("Host: ") + 6;
There are many issues in your code:
1) Change the line :
int start = browserRequest.indexOf(("Host: ") + 6);
To:
int start = browserRequest.indexOf("Host:") + 6;
As mentioned in ToYonos's answer, becuase it is wrong.
2) You have to make sure that the two variables start and end are not equal to -1(if they doesn't exist in browserRequest):
if(end>start && start>0)
{
String host = browserRequest.substring(start, end-1 );
}
This will avoid many Exceptions.
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.