Hi,
ich bastle gerade an einem multithreaded SocketListener sowohl für eine Anzahl UDP- als auch TCP-Ports. Die Anwendung läuft auf einem Debian-Linux. Verwendet werden soll sie als Server-Gegenstück zu einem Java-Client der bei mehreren hundert Nutzern läuft. D.h. es kann durchaus mal vorkommen, dass 2 oder mehr Nutzer gleichzeitig den Listener ansprechen.
Allerdings habe ich ein Problem bereits mit einzelnen Requests: die TDP-Ports schließen sich einfach wieder nach einiger Zeit (immer unterschiedlich). Ich sehe irgendwie keinen Grund dafür. Vlt. kann mir hier jemand dazu einen Tipp geben? UDP geht btw. einwandfrei.
ich bastle gerade an einem multithreaded SocketListener sowohl für eine Anzahl UDP- als auch TCP-Ports. Die Anwendung läuft auf einem Debian-Linux. Verwendet werden soll sie als Server-Gegenstück zu einem Java-Client der bei mehreren hundert Nutzern läuft. D.h. es kann durchaus mal vorkommen, dass 2 oder mehr Nutzer gleichzeitig den Listener ansprechen.
Allerdings habe ich ein Problem bereits mit einzelnen Requests: die TDP-Ports schließen sich einfach wieder nach einiger Zeit (immer unterschiedlich). Ich sehe irgendwie keinen Grund dafür. Vlt. kann mir hier jemand dazu einen Tipp geben? UDP geht btw. einwandfrei.
Java:
package Main;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
/**
* Multi-threaded multisocket-listener which will act as server-side
* application to check if users have specific ports open
* in their network/firewall.
*
* If a client connects on one of the ports,
* the application sends a simple 1 and closes the connection.
*
*/
public class socketListener {
Socket cs;
private String logfile = "";
private ServerSocket ss;
private ArrayList<Integer> tcpPorts = new ArrayList<Integer>();
private ArrayList<Integer> udpPorts = new ArrayList<Integer>();
private InputStream inputStream;
private String result = "";
private Logger logger;
socketListener(Socket cs){
this.cs = cs;
}
/**
* Main function for this app.
* The arguments will not be used.
*
* @param args
* @throws InterruptedException
* @throws IOException
*/
public static void main(String args[]) throws InterruptedException, IOException{
System.setProperty("java.net.preferIPv4Stack" , "true");
new socketListener();
}
/**
* Start the listener.
*/
public socketListener() {
try {
// read config.properties-file
this.getPropValues();
// if logfile is set use it
if( this.logfile.length() > 0 ) {
// create a logger
logger = Logger.getLogger("log");
// create a filehandler
FileHandler fh = new FileHandler(this.logfile);
// set the filehandler as destination where the file will be written
logger.addHandler(fh);
// create and set a format for the logfile
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
}
} catch (IOException e) {
e.printStackTrace();
}
// add all tcp-ports to the array
for( int p = 2300; p <= 2400; p++ ) {
tcpPorts.add(p);
}
tcpPorts.add(47624);
// add all udp-ports to the array
for( int p = 2300; p <= 2400; p++ ) {
udpPorts.add(p);
}
udpPorts.add(1900);
try {
// start the tcp-port-listener
tcpPortListener();
// start the udp-port-listener
udpPortListener();
} catch (InterruptedException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* UDP-Port-listener for the given list of ports.
* Sends the received message back to sender.
*
* @throws InterruptedException
* @throws IOException
*/
private void udpPortListener() throws InterruptedException, IOException {
// loop through the ports and open a listener for each
for( int udpPort: udpPorts ) {
// wait 100ms before adding the next port-listener as it may be to fast
Thread.sleep(100);
// make it runnable as we need to listen to many ports at the same time
Runnable runnable = new Runnable(){
public void run(){
DatagramSocket serverSocket = null;
try {
// open port
serverSocket = new DatagramSocket(udpPort);
debug("Server Listening on udp-port " + udpPort);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
// wait if we got a message
while(true)
{
// get the message we received
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
debug("RECEIVED on udp port " + udpPort + ": " + sentence);
// get the ip-address of the caller
InetAddress IPAddress = receivePacket.getAddress();
// get the port where the caller sent from
int port = receivePacket.getPort();
// format the message
String capitalizedSentence = sentence.toUpperCase();
// get the message-bytes
sendData = capitalizedSentence.getBytes();
// send the package back to given ip and port
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
} catch (NumberFormatException | SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
// quit the listener on the port
if( serverSocket instanceof DatagramSocket ) {
serverSocket.close();
}
}
}
};
Thread thread = new Thread(runnable);
thread.setName("udpPort" + udpPort + "Thread");
thread.start();
}
}
/**
* TCP-Port-listener for the given list of ports.
* Sends a "1" back to sender and close the connection after it.
*
* @throws InterruptedException
*/
private void tcpPortListener() throws InterruptedException {
// loop through the ports and open a listener for each
for( int port: tcpPorts ) {
// wait 500ms before adding the next port-listener as it may be to fast
Thread.sleep(500);
// make it runnable as we need to listen to many ports at the same time
Runnable runnable = new Runnable(){
public void run(){
try {
// take the port
ss = new ServerSocket(port);
debug("Server is now listening on tcp-port " + port);
// wait for a connection
while(true){
// new connection from a client
Socket newClient = ss.accept();
// debug-output
debug(newClient.getInetAddress() + " has connected on tcp port " + port);
try {
// send a simple "1" back to the client to proof that the connection was successfully
PrintWriter out = new PrintWriter(newClient.getOutputStream(), true);
out.println("1");
} finally {
// then close the connection to the client
newClient.close();
}
}
}
catch(IOException e) {
System.out.println("tcp-Port " + port + " already taken (maybe other programm?)");
}
finally {
// quit the listener on the port
try {
debug("Server Listening on tcp port " + port + " ended");
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
thread.setName("tcpPort" + port + "Thread");
thread.start();
}
}
/**
* Output the given debug-string on the console.
*
* @param text
* @throws IOException
*/
private void debug( String text ) {
if( this.logger != null ) {
this.logger.info(text);
}
// output to console
System.out.println(text);
}
/**
* Read data from config-file.
*
* @return
* @throws IOException
*/
public String getPropValues() throws IOException {
try {
Properties prop = new Properties();
String propFileName = "config.properties";
inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
if (inputStream != null) {
prop.load(inputStream);
} else {
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
}
// get a single property from file
logfile = prop.getProperty("logfile");
} catch (Exception e) {
debug("Exception: " + e);
} finally {
if( inputStream != null ) {
inputStream.close();
}
}
return result;
}
}
Zuletzt bearbeitet von einem Moderator: