Find text into response using expression - java

I have this code which I want to use to check domain registration:
private final static String WHO ="cnn.com";
private final static String WHOIS_HOST = "whois.verisign-grs.com";
private final static int WHOIS_PORT = 43;
public static void main(final String[] args) throws IOException {
SpringApplication.run(TestApplication.class, args);
int c;
Socket socket = null;
String query = WHO + "\r\n";
byte buf[] = query.getBytes();
String regex = ".*Registry Expiry Date:*";
try {
socket = new Socket(WHOIS_HOST, WHOIS_PORT);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
out.write(buf);
out.flush();
StringBuilder text = new StringBuilder();
while ((c = in.read()) != -1) {
System.out.print((char) c);
text.append(c);
}
boolean matches = Pattern.matches(regex, text.toString());
System.out.print("\nDone\n" + matches);
} catch (IOException ex) {
System.out.print(ex.getMessage());
} finally {
if(socket != null){
try {
socket.close();
} catch (IOException ex) {
}
}
}
}
I get this output:
Domain Name: CNN.COM
Registry Domain ID: 3269879_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.corporatedomains.com
Registrar URL: http://cscdbs.com
Updated Date: 2018-04-10T16:43:38Z
Creation Date: 1993-09-22T04:00:00Z
Registry Expiry Date: 2026-09-21T04:00:00Z
Registrar: CSC Corporate Domains, Inc.
Registrar IANA ID: 299
Registrar Abuse Contact Email: domainabuse#cscglobal.com
Registrar Abuse Contact Phone: 8887802723
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited
Domain Status: serverTransferProhibited https://icann.org/epp#serverTransferProhibited
Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
Name Server: NS-1086.AWSDNS-07.ORG
Name Server: NS-1630.AWSDNS-11.CO.UK
Name Server: NS-47.AWSDNS-05.COM
Name Server: NS-576.AWSDNS-08.NET
DNSSEC: unsigned
URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2022-07-29T20:55:54Z <<<
For more information on Whois status codes, please visit https://icann.org/epp
NOTICE: The expiration date displayed in this record is the date the
registrar's sponsorship of the domain name registration in the registry is
currently set to expire. This date does not necessarily reflect the expiration
date of the domain name registrant's agreement with the sponsoring
registrar. Users may consult the sponsoring registrar's Whois database to
view the registrar's reported date of expiration for this registration.
TERMS OF USE: You are not authorized to access or query our Whois
database through the use of electronic processes that are high-volume and
automated except as reasonably necessary to register domain names or
modify existing registrations; the Data in VeriSign Global Registry
Services' ("VeriSign") Whois database is provided by VeriSign for
information purposes only, and to assist persons in obtaining information
about or related to a domain name registration record. VeriSign does not
guarantee its accuracy. By submitting a Whois query, you agree to abide
by the following terms of use: You agree that you may use this Data only
for lawful purposes and that under no circumstances will you use this Data
to: (1) allow, enable, or otherwise support the transmission of mass
unsolicited, commercial advertising or solicitations via e-mail, telephone,
or facsimile; or (2) enable high volume, automated, electronic processes
that apply to VeriSign (or its computer systems). The compilation,
repackaging, dissemination or other use of this Data is expressly
prohibited without the prior written consent of VeriSign. You agree not to
use electronic processes that are automated and high-volume to access or
query the Whois database except as reasonably necessary to register
domain names or modify existing registrations. VeriSign reserves the right
to restrict your access to the Whois database in its sole discretion to ensure
operational stability. VeriSign may restrict or terminate your access to the
Whois database for failure to abide by these terms of use. VeriSign
reserves the right to modify these terms at any time.
The Registry database contains ONLY .COM, .NET, .EDU domains and
Registrars.
Done
false
Do you know how I can get only the line content Registry Expiry Date: 2026-09-21T04:00:00Z?

there is a problem in the while you are appending the byte value to StringBuilder so the matcher doesn't works if you change like this way you can have the value of the regex you need
StringBuilder text = new StringBuilder();
while ((c = in.read()) != -1) {
// System.out.print((char) c);
text.append((char) c);
}
System.out.println(text);
String regex = ".*Registry Expiry Date.*Z";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text.toString());
if (matcher.find())
{
System.out.println("\nDone\n" + matcher.group(0));
}
in this case the result will be
Done
Registry Expiry Date: 2026-09-21T04:00:00Z

There are a few things to clean up:
c is defined as an int, so when you call text.append(c), you are appending an integer value – to fix that, you can cast "c" to be a character: text.append((char) c)
your code reads the entire response into a StringBuilder, then processes that text afterward, looking for any potential matches – this isn't a huge inefficiency, but it's not necessary either; you could instead inspect the data along the way to see if you've encountered the interesting part of the data and if so, skip processing the rest
Using Pattern and Matcher is ok, but for the case you've presented, it's extra complexity.
Here's a solution that:
Opens the socket and "out" in a try-with-resources block – that way, both will be closed for you automatically (simpler code)
Opens the input stream in a try-with-resources block – again, less code, automatic management of the opened resources
Wraps the input stream in a BufferedReader – this allows you to read the input line by line
In the while loop, instead of using Pattern and Matcher, it simply checks if each line of text contains "Registry Expiry Date"
If a match is found, it prints the match, then breaks from the loop – it isn't necessary to look at any more input data
String WHO = "cnn.com";
String WHOIS_HOST = "whois.verisign-grs.com";
int WHOIS_PORT = 43;
try (Socket socket = new Socket(WHOIS_HOST, WHOIS_PORT)) {
try (OutputStream out = socket.getOutputStream()) {
out.write((WHO + "\r\n").getBytes());
out.flush();
try (BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
String line;
while ((line = input.readLine()) != null) {
if (line.contains("Registry Expiry Date")) {
System.out.println("---> " + line);
break; // don't need to read any more input
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
Here's the output:
---> Registry Expiry Date: 2026-09-21T04:00:00Z

Related

Buffered Reader returns unexpected character from user input

I have a multi-chat server client program and I am attempting to get input from a client in a telnet putty window.
The prompt:
String login = "2-Enter Username and a password:";
clientoutput.write((login).getBytes());
The user input:
This is read by a BufferedReader:
BufferedReader br = new BufferedReader(new InputStreamReader(clientInput));
String inputLine;
String returnMessage;
while ((inputLine = br.readLine()) != null) {
// Split input line with space as delimiter using import jar
String[] words = StringUtils.split(inputLine);
// Ensure we don't get a null pointer
if (words != null && words.length > 0) {
String command = words[0];
if ("logoff".equalsIgnoreCase(command) || "q".equalsIgnoreCase(command) || "quit".equalsIgnoreCase(command)) {
logOff();
break;
}else
// Log user in
try {
clientLogIn(clientoutput, words);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
However the first word of user input is consistently read as
ÿû
:
Eclipse console output:
User ÿû has logged in
So my question is where is this character ÿû coming from and is there a work around?
I am using WIndows 10 and Eclipse Version: 2019-03 (4.11.0)
Build id: 20190314-1200
Additional info:
I've tried to capture the user input and directly print to console :
if (login.contains("ÿû")) {
login = login.substring(1);
System.out.println("New login after removal of unxepected char: " + login);
} else {
System.out.println("User eneterd login : " + login);
}
Output:
User entered login : -Enter Username and a password:
User ÿû has logged in // after the first word has been taken
Since you're actually writing your own protocol, the problem seems to be that you're using the wrong client to test your server.
That is, telnet is not meant as a general TCP client, as it sends commands alongside the actual data you're trying to send. Also, it works on bytes, not java strings (which you noticed when you tried to check for those weird chars at the beginning of the string).
You may avoid the problem completely if you used something like netcat to test your code instead.
You got telnet protocol special bytes 0xff (IAC) and 0xfb (WILL).
If you need to avoid it in your application, use this specification (section you need is "TELNET COMMAND STRUCTURE") to skip protocol specific bytes.

Selenium to check log files

Does anyone know if it is possible to use selenium WebDriver (im using java) to check for messages in log files?
Currently the only way to know if an action in the front end of our system has completed is to ssh into our servers and wait for confirmation from the log files. This is how the process is tested manually but now I need to automate that test. Is it possible to use selenium to check this out?
My current method to achieve this seems overly complex:
Run actions in Front end
Launch shell Script to check log files from Selenium Test (includes ssh to server as logs are stored there)
Create "Action Completed" message in simple text file on server if logs show action is completed otherwise show "Action NOT completed"
scp file back to my machine/VM
read in file to eclipse
Create method in test to check contents of file something like if ("Action completed" message is returned -> continue) else (repeat from bullet point 2)
Is there a simpler way???
Self Answer - After considering all the posts, this is the solution I came up with that works really well. I have wirtten a method which allows me to parse the logs using regex right from Eclipse. Below is the code with heavy commenting to show what I have done....
public void checkLogs() throws IOException{
//create an empty string to hold the output
String s = null;
// using the process API and runtime exec method to directly ssh in the client machine and run any command you like. I need the live logs so I used tail -f
Process p = Runtime.getRuntime().exec("ssh user#ipaddress tail -f /location/file");
// use buffered reader to bring the output of the command run on the clinet machine back to the output in eclipse. I also created an output for the error stream to help with debugging if the commands dont work as I am not directly looking at the output when I run the commands on the client machine
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
// For my test I only want to continue with the clicks in the front end once I know the system has been reset. For our system this can only be checked in the logs. So I created a boolean flag which will only become true once the regex I run matches lines from the output. Use a while loop with != null to check every line of the output
boolean requestArrived = false;
while ((s = stdInput.readLine()) != null) {
System.out.println(s); // so I can see live what is happening. (great for debugging)
//search for the specific string that lets me know the system has been started the reset. (can run any regex here)
if(r.equalsIgnoreCase("system reset request received")){
System.out.println("***********************************************************************************************");
// Change the state of the boolean flag to true as we know now that the backend is ready to continue
requestArrived = true;
}
if(t.equalsIgnoreCase("System reset has happened successfully"))// a secondary check to see when the system is ready to continue{
System.out.println("##############################################################################################");
//if both string that we are looking for have been received we can continue with the rest of the script
if (requestArrived) {
break;
}
}
}
//close the terminal
p.destroy();
}
I hope that helps someone :)
Add a special page to your site that tails the logfile. Have a shared secret that selenium knows and the site if you need to keep the logfile confidential. Then just visit that page and use the usual methods to check for strings
There may be some permissions problems to overcome: normally web applications shouldn't be able to see the logs.
With the present solution you describe, Selenium is not really the right tool for the job (even though you could probably find a solution).
I can see several possible approaches:
Add a page that shows the progress (as suggested by Vorsprung). This could be a separate page, or some message in the existing GUI. This could be only for Selenium, or maybe it could even become a proper feature for all users (or only for administrators), if it makes sense for your system.
Use a system like you describe, but run the server on the local system (as a special test instance). Then you can skip the SSHing.
Create some service (REST or similar) on the server to query job status. Again, this may be useful for more than just testing.
What makes sense depends on how the system is used (how users currently check whether a job has completed, what information about a job is interesting, etc.).
EDIT: I misread your question, As you were asking for a simpler solution, but I tried to provide solution for the complex approach. Anyways I hope it will be useful.
Actual Answer:
I had done following activity for my project
clear logs using a shell script on remote unix server
Perform front end activity
capture logs after predefined time (say, 60 seconds )
SFtp back to client machine
first you will need an SFTP client and SSH client to interact with unix server
here Node is an object containing Unix env details. so change accordingly.
Using JSch lib for this
public static String runCommand(String Command, Node node )
{
String output = null;
if (node.getConnType().equals("SSH")){
int exitStatus = 0;
try{
JSch jsch=new JSch();
JSch.setConfig("StrictHostKeyChecking", "no");
Session session=jsch.getSession(node.getUserName(), node.getHost(), 22);
session.setPassword(node.getPassword());
session.setConfig("PreferredAuthentications",
"publickey,keyboard-interactive,password");
session.connect();
String command=Command;
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in=channel.getInputStream();
channel.connect();
byte[] tmp=new byte[1024];
while(true){
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;
output = new String(tmp, 0, i);
}
if(channel.isClosed()){
if(in.available()>0) continue;
exitStatus= channel.getExitStatus();
//System.out.println("exit-status: "+exitStatus);
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
channel.disconnect();
session.disconnect();
}
catch(Exception e){
e.printStackTrace();
}
if (exitStatus == 0)
{
if(output != null)
return output.replaceAll("[\\n\\r]", "");
}
}
return null;
}
SFTP client
public boolean transferFileSFTP(Node node,String srcDir,String targetDir,String srcFileName,String targetFileName, String direction)
{
JSch jsch = new JSch();
Session session = null;
try {
session = jsch.getSession(node.getUserName(), node.getHost(), 22);
session.setConfig("StrictHostKeyChecking", "no");
session.setConfig("PreferredAuthentications",
"publickey,keyboard-interactive,password");
session.setPassword(node.getPassword());
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
System.out.println("src:" + srcDir+srcFileName );
System.out.println("target:" + targetDir+targetFileName );
sftpChannel.get(targetDir+targetFileName, srcDir+srcFileName);
sftpChannel.exit();
session.disconnect();
return true;
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
return false;
}
Now,
To wait until desired time and make it thread based to collect logs simultaneously from different applications involved,
using ExecutorService and Future<String> utilities
So created one LogCollector class which will initiate request and another is ThreadClass(logical) which will perform activities on log file.
LogCollector.java
public class LogCollector {
private static ExecutorService pool = Executors.newFixedThreadPool(100);
private static List<Future<String>> list = new ArrayList<Future<String>>();
public static void add(Node node, String srcDir, String targetDir, String srcFileName, String targetFileName, long wait )
{
list.add(pool.submit(new LogCollectorThread(System.currentTimeMillis()/1000,wait, srcDir, targetDir, srcFileName, targetFileName, node )));
}
public static void getResult()
{
try{
for (Future<String> future : list) {
String out =future.get();
//DO whatever you want to do with a response string return from your thread class
}
pool.shutdown();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
LogCollectorThread.java
public class LogCollectorThread implements Callable<String>{
long startTime;
long wait;
String srcFileName;
String targetFileName;
String srcDir;
String targetDir;
Node node;
public LogCollectorThread(long startTime, long wait,String srcDir, String targetDir,String srcFileName, String targetFileName,
Node node) {
super();
this.startTime = startTime;
this.wait = wait;
this.srcFileName = srcFileName;
this.targetFileName = targetFileName;
this.srcDir = srcDir;
this.targetDir = targetDir;
this.node = node;
}
/***
* Returns a String with Parameters separated by ',' and status at the end
* status values:
* 0 - successfully retrieved log file
* 1 - failure while retrieving log file
*/
#Override
public String call() throws Exception {
while((System.currentTimeMillis()/1000 - startTime)<=wait)
{
Thread.sleep(1000);
}
MyFTPClient sftp= new MyFTPClient();
boolean result =sftp.transferFileSFTP(this.node, this.srcDir, this.targetDir, this.srcFileName, this.targetFileName, "From");
System.out.println(this.node.getHost() + ","+ this.srcDir + ","+this.targetDir +","+ this.srcFileName +","+ this.targetFileName);
if(result == true)
return this.node.getHost() + ","+ this.srcDir + ","+this.targetDir +","+ this.srcFileName +","+ this.targetFileName +"," + "0" ;
else
return this.node.getHost() + ","+ this.srcDir + ","+this.targetDir +","+ this.srcFileName +","+ this.targetFileName +"," + "1" ;
}
}
How to use LogCollector classes:
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
Helper.runCommand("cd /opt/redknee/app/crm/current/log/; echo > AppCrm.log", testEnv.getBSS());
LogCollector.add(testEnv.getBSS(), "collectedLogs\\", "/opt/redknee/app/crm/current/log/", timeStamp + "_" + testEnv.getBSS().getHost() + "_BSS_AppCrm.log" , "AppCrm.log", 60);
//So your thread is working now, so now perform your Front End Activity
//After 60 seconds, log file will be SFTPed to client host
//You can perform you activity before adding logCollectorThread or just before that
LogCollector.getResult();
Here I have given too much code,
But it is too hard to describe each step line by line.
Main thing i wanted to prove is using java most of the things are possible.
It is upto you to decide how critical it is and is it worth doing.
Now coming to your exact requirement of searching for a particular string.
As you can see in logCollectorThread,
currently i am doing nothing but just waiting till 60 seconds to complete.
So here you can use runCommand to grep desired string from logs
you can use command like
grep -i "Action Completed" | grep -v 'grep' | wc -l
if it return 1, you found your string
Similarly you can check for failure message.
and return desired string from your thread and get it as result in threadCollector.getResult() method.
And Once file is FTPed to your client, parsing it for a particular string using Java would be very easy. StackOverflow will help you in that :)
declaimer: don't expect code to be fully working.
It will work but you have to put your efforts. your java knowledge will be needed to plug-in the missing pieces
To check the action got completed, checking server logs might be solution. But still in GUI, we could see visibility of some html elements or messages or java script variable or overriding javscript functions.
With the help of Selenium JavscriptExecutor, we can override alert method (refer example 21)similarly we can override onreadystatechange for the request/response completion.
JavaScript Window variables can be used to show the action completeness by checking after each ajax request.
We can use selenium wait to wait for an element to be visible, identify an element using xpath.
There are more tutorials available in the below link for element wait, typing in textbox and so on.
http://software-testing-tutorials-automation.blogspot.com/2014/05/selenium-webdriver-tutorials-part-two.html

How to get the remote user's username in java

I am working on application which doesn't have any login mechanism, any user in my organization can use that. But I want to pick the username of the remote users who will use my tool. I have a button clicking on that I want to get their usernames.
I tried request.getRemoteUser got null. tried System.getenv("USERNAME") getting the logged in user of the localhost where the server resides. Tried getHostName, System.getProperty got the localhost name. Tried this also - new com.sun.security.auth.module.NTSystem().getName() but same result.
I am using java6, windows server and glassfish3 server.
Please suggest something as I don't want to use any external link and tool.
You want to do something called SSO (Single Sign On): A user is logged in somewhere (in your case his Windows computer) and you want to authenticate the user with this (already done) login. This is a very common use case and there are different ways to do that. However, the big question is always how you can trust those third party system. And this is where the trouble begins.
Since your question is not very clear, I assume you have a Java Glassfish server running on Windows Server and a Java client (because you asked for Java code). So the Java server must authenticate who the user of the Java client is. And the server must trust this information.
Using System.getProperty("user.name"); isn't a good idea since anybody can change it. You can start your Java program with java -Duser.name=Joe <your_program> and that's it.
But since you are on Windows, you could use Windows to help you. If both, your client and server, are in the same domain, they are authenticated against the same system. You can ask this system for the user identity. Typically machines of a company are in the same domain.
To do this there is a tool called Waffle. It does a secure Windows authentication between machines in the same domain. If your client and server are in the same domain, it is an easy way to perform an SSO (a single sign on). You can find it on GitHub: http://dblock.github.io/waffle/
Here is a simple example from one of my own questions a couple of months ago (see here):
// client credentials handle
IWindowsCredentialsHandle credentials= WindowsCredentialsHandleImpl.getCurrent("Negotiate");
credentials.initialize();
// initial client security context
WindowsSecurityContextImpl clientContext = new WindowsSecurityContextImpl();
clientContext.setPrincipalName(Advapi32Util.getUserName());
clientContext.setCredentialsHandle(credentials.getHandle());
clientContext.setSecurityPackage(securityPackage);
clientContext.initialize();
// accept on the server
WindowsAuthProviderImpl provider = new WindowsAuthProviderImpl();
IWindowsSecurityContext serverContext = null;
do {
if (serverContext != null) {
// initialize on the client
SecBufferDesc continueToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, serverContext.getToken());
clientContext.initialize(clientContext.getHandle(), continueToken);
}
// accept the token on the server
serverContext = provider.acceptSecurityToken(clientContext.getToken(), "Negotiate");
} while (clientContext.getContinue() || serverContext.getContinue());
System.out.println(serverContext.getIdentity().getFqn());
for (IWindowsAccount group : serverContext.getIdentity().getGroups())
System.out.println(" " + group.getFqn());
You can use Waffle also for websites. However, I didn't do that and cannot explain you what to do in this case.
And one important remark: I think you are a little bit confused. If you do request.getRemoteHost() on your server, you try to get the identity of the client who send the request (by the way, it is not secure, a client could send anything). However, if you do System.getProperty("user.name") on your server, you try to get the name of the server itself. Be aware where you are (on client or server) and what you want. And make sure whether you can trust this information or not. Security is difficult.
java class code to find who loggedin into a remote computer in a domain
package com.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import com.test.Pubfun;
public class UserName {
public static HashMap <String,String> hmun=new HashMap<String, String>();
public String setUserFromIP(String arg1) {
String m = arg1;
StringBuilder user = new StringBuilder();
String u = "";
String user2 = null;
try {
Process p = Runtime.getRuntime().exec("query user /server:" + m);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line = reader.readLine();
while (line != null) {
line = reader.readLine();
user.append(line);
line=null;
}
} catch (IOException e1) {
} catch (InterruptedException e2) {
}
u = user.toString().replace("null", "");
try {
user2 = this.getUserFromString(u);
} catch (ArrayIndexOutOfBoundsException ae) {
}
u.replace("null", " ");
System.out.println(user2);
hmun.put("username",user2);
return user2;
}
public static String gethmun()
{
String t=hmun.get("username");
return t;
}
public String getUserFromString(String u) {
HashMap <String,String> hmun=new HashMap<String, String>();
String input = u;
int length, size;
length = input.length();
size = length ;
String strarray[] = new String[size];
strarray = input.split("\\s+");
for (int i = 0; i < strarray.length; i++) {
if(strarray[i].equals("Active")){
hmun.put("username", strarray[i-3]);
}
}
String user1=hmun.get("username");
return user1;
}
}
HttpServletRequest.getRemoteUser() might optionally return the login of user making the request (if authenticated), but it is not the username of the user logged in on the remote machine.
There is no way to query the username of the remote machine. Browsers or applications making the requests might send this info voluntarily, but if they don't, you won't find a way to get it. And by default they don't send it so don't count on this.
This gives you the current logged in Username from your local Windows System System.getProperty("user.name");

Narrow communication to a specific client in chat application java

I just created an java chat application that allow a communication between many clients, however, i would like also to have the ability to one client send a message to a specific client, the others client cannot be able to see the message send, just like one client whispering to another one. Thank you in advance.
Here some part of my client
public void sendListener(){
writer.println(clientName2+" : "+broadcastTF.getText() );
writer.flush();
broadcastTF.setText("");
broadcastTF.requestFocus();
}
public class listenServer implements Runnable{
public void run(){
try{
String text;
while((text = reader.nextLine()) != null){
messageTA.append(text+ "\n");
}
}catch(Exception ex){}
}
}
private void setupServer(){
try{
socket = new Socket("127.0.0.1", 7894);
writer = new PrintWriter(socket.getOutputStream());
reader = new Scanner(socket.getInputStream());
listenServer ls = new listenServer();
Thread t = new Thread(ls);
t.start();
}
catch(Exception ex){
}
}
Here some part of my server
public class listenToClient implements Runnable{
Scanner reader;
public listenToClient(Socket socket){
try{
reader = new Scanner(socket.getInputStream());
}catch (Exception ex){}
}
public void run(){
try{
String text;
while((text = reader.nextLine()) != null){
sendToAll(text);
}
}catch(Exception ex){}
}
public void sendToAll(String text){
for (PrintWriter w : writers){
try{
w.println(text);
w.flush();
}catch(Exception ex){}
}
}
}
I think this is less related to specific code, and more related to overall design.
Primarily, you'd need some way of identifying individual clients. If you need fast lookups, you would use some sort of key/value map to store your writers, with the unique ID (user name, user ID, some random string, or whatever suits your situation) as the key. If that's not a concern, then you can store your client connections in a simple numerical array (or array-like structure) and iterate over until you find the target, then send to exclusively that connection.
Then, the sending client needs to be able to discern what its target is, and also have some way of sending the target information along with the message. Simply reading input at the server and echoing it out will not suffice for this - you'll have to do some amount of parsing, and you'll probably need to design some format for arranging that information.
As an example, one client-server communication format I designed had the first byte of a message be the length of the key in a key/value pair. The server would read the first byte, then read the next N bytes as the key. The remaining bytes were then known to be the value. In your case, a key length of 0 would mean it's not going to one specific destination, but to everyone.
Create a collection of clients such as hashmap. So whenever you get a new client connection accept, assign this client an id and put its socket reference against the id in the hashmap.
Clients should know each other ids to make sure that they can identify and send the messages to each other. So whenever a client sends a packet to server and it contains a recepient client id, server should lookup the hashmap. The recepient socket reference should be retrieved and message should be sent using the writer.
Hope it helps!

Java Killswitch

I've created a java application I'm selling for money, and the verification system involves using an unique HWID to ID the computer to see if they've paid. I was wondering if there was a way for a java application to "kill" itself, maybe deleting some of it's own class files, corrupting itself, or overriding itself.
Is there any way?
Make it web based, keep records in the database, make the user log in to use the system. Any dedicated cracker will defeat your system in a matter of time.
If this is a commercial grade app, then I would recommend using a security solution designed by professionals. Security and Cryptography is best left to experts
Layman solution :
Could you execute a getmac (assuming this app runs out of windows) from within your system and do the check.? MAC ids are assumed to be unique for a PC. There are ways to override it but should address 90% of the cases.
Corrupting your app doesn't seem to be a good solution.
public static String getURLSource(String link) {
try {
URL url = new URL(link);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder str = new StringBuilder();
String inputLine;
while ((inputLine = reader.readLine()) != null) {
str.append(inputLine);
}
reader.close();
return str.toString();
} catch (Exception e) {
throw new RuntimeException("Couldn't properly connect to internet.");
}
}
public void main(String[] args) {
if(!getUrlSource("yourlink").contains("a string you want when it's not killswitched")) { //The link must be readable text by java
//Do stuff here
}
}

Categories