Java private messaging - java

i am having a problem with private messages in java. I ask the user for a "name" when they launch the Client, and it is a variable in ChatClient.java file. I have made it "public", but when i try to call it in the ChatServer.java it says "cannot find symbol". Any help with that? Also in this snippet i am searching for the right "name" from users, should there be anything defiying the "i" name? (like i.name or some sort of connection between the current client and their name).
ChatServer problematic part
public void sendPrivate(String message) throws Exception {
Iterator<Socket> i = clients.iterator();
StringTokenizer st = new StringTokenizer(message.substring(7,message.length()),", ");
String realMessage = st.nextToken();
String to = st.nextToken();
while (i.hasNext()) {
Socket socket = (Socket) i.next();
try {
if (name.equals(to)){
DataOutputStream out = new DataOutputStream(socket.getOutputStream()); // create output stream for sending messages to the client
out.writeUTF(realMessage); // send message to the client
}
}
catch (Exception e) {
System.err.println("[system] could not send message to a client");
e.printStackTrace(System.err);
}
}
}
ChatClient part where the user inputs their "name"
public class ChatClient extends Thread
{
public String name;
protected int serverPort = 8888;
public static void main(String[] args) throws Exception {
new ChatClient();
}
public ChatClient() throws Exception {
Socket socket = null;
DataInputStream in = null;
DataOutputStream out = null;
//whitelistaned
String[] whitelist = {"Bob", "Frank", "Goliath", "Zealot", "Bruce Wayne"};
int aliUstrezas = 0;
//common courtesy
System.out.println();
System.out.println("Would you fancy in telling me your name, sir ?");
System.out.println("Current whitelist: {'Bob', 'Frank', 'Goliath', 'Zealot', 'Bruce Wayne'} ");
Scanner sc = new Scanner(System.in);
name = sc.nextLine();

ChatServer does not instantiate a object of type ChatClient, so it does not matter if name is public or not, it can not magically read variables from any arbitrary object.

Related

json file not arriving complete when using sockets

I have a stream of video. And every frame I need to send a small json file with data from that frame, speed it´s crucial. Whats the best way to do this?
My Server is something like this. Waits for a json file and then has to send that json file to a python application.
public class ServerClass {
public static void main(String[] args) {
Marcoserver mimarco=new Marcoserver();
}
}
class Marcoserver implements Runnable {
public Marcoserver(){
Thread miHilo = new Thread(this);
miHilo.start();
}
public void run() {
try {
ServerSocket server = new ServerSocket(7777);
while (true) {
Socket miSocket = server.accept();
BufferedReader entrada = new BufferedReader(new InputStreamReader(miSocket.getInputStream(), "UTF8"));
String mensaje = entrada.readLine();
JSONObject obj;
obj = new JSONObject(mensaje);
System.out.println(obj);
ConectorSocket cntor = new ConectorSocket("localhost", 6363);
cntor.Conectar();
cntor.Send(mensaje);
cntor.Close();
miSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ConectorSocket{
private String host;
private int port;
Socket sockSend;
public ConnectClass(String hst, int prt ) {
this.host = hst;
this.port = prt;
}
public void Conectar() {
this.sockSend = new Socket(this.host, this.port);
}
public void Send(String mensaje) {
DataOutputStream flujo_salida = new DataOutputStream(sockSend.getOutputStream());
flujo_salida.writeBytes(mensaje);
flujo_salida.close();
}
public boolean Close() {
this.sockSend.close();
}
}
This is the python app simplified:
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('localhost', 6666))
serversocket.listen()
while True:
connection, address = serversocket.accept()
buf = connection.recv(2048)
if len(buf) > 0:
print(buf.decode())
My problem is that the python app prints incomplete information such as:
{"keyword"
{"keyword": [[14, 1, -1]]}
{"keyword": [[14,
instead of:
{"keyword":[]}
{"keyword":[[14,1,-1]]}
{"keyword":[[14,2,-1]]}
There's nothing wrong with your Java code, but your Python code is not good:
while True:
connection, address = serversocket.accept()
buf = connection.recv(2048)
if len(buf) > 0:
print(buf.decode())
That will print just the first received TCP packet for each connection.
You need to continue calling recv until it returns 0:
while True:
connection, address = serversocket.accept()
msg = []
while True:
buf = connection.recv(65536)
if (len(buf) == 0):
break
msg.append(buf)
print(''.join(msg))
connection.close()
You also need to close each connection.

How to connect two different PCs between two different networks using a java chat application?

I have a chat application client server which run on a LAN without a server.
this is the server class:
import java.net.*;
import java.io.*;
public class Server {
private ServerSocket server;
private Socket connessione;
private BufferedReader dalClient;
private PrintStream alClient;
private String name;
public Server(String name) {
this.name = name;
try {
InetAddress IP=InetAddress.getLocalHost();
System.out.println("IP of my system is := "+IP.getHostAddress());
server = new ServerSocket(1000, 5);
System.out.println("Server attivo");
connessione = server.accept();
dalClient = new BufferedReader(new InputStreamReader(connessione.getInputStream()));
alClient = new PrintStream(connessione.getOutputStream());
}
catch(IOException e) {
System.out.println(e);
}
} // Server()
public void conversazione() {
String messaggio = "";
BufferedReader t = new BufferedReader(new InputStreamReader(System.in));
try {
alClient.println("Sei connesso al server! Digita /logout per effetuare la disconnessione.\n");
while(!messaggio.equals("/logout")) {
messaggio = dalClient.readLine();
System.out.println(messaggio);
if(!messaggio.equals("/logout")) {
messaggio = t.readLine();
alClient.println(name+" scrive: "+ messaggio);
}
} // while
}
catch(IOException e) {
System.err.println("Conversazione interrotta");
}
}
}
and this is the client class:
import java.net.*;
import java.io.*;
public class Client {
private Socket connessione;
private BufferedReader dalServer;
private PrintStream alServer;
private String name;
public Client(String name) {
this.name = name;
BufferedReader t = new BufferedReader(new InputStreamReader(System.in));
try {
int porta = getLocalPort();
System.out.println("Porta locale: " + porta);
System.out.println("Inserire indirizzo IP server: ");
String indirizzo = t.readLine();
connessione = new Socket(indirizzo, 1000);
dalServer = new BufferedReader(new InputStreamReader(connessione.getInputStream()));
alServer = new PrintStream(connessione.getOutputStream());
} catch(IOException e) {
System.out.println(e);
}
} // Client()
public void conversazione() {
String messaggio = "";
BufferedReader t = new BufferedReader(new InputStreamReader(System.in));
try {
while(!messaggio.equals("/logout")) {
messaggio = dalServer.readLine();
System.out.println(messaggio);
if(!messaggio.equals("/logout")) {
messaggio = t.readLine();
alServer.println(name+" scrive: "+messaggio);
}
} // while
connessione.close();
}
catch(IOException e) {
System.out.println("Conversazione interrotta");
}
} // conversazione()
}
and i have other two class files which i use to run the codes above that are the follow:
this is the class which i execute to run the server side:
public class ProvaServer {
public static void main(String[] args) {
Server s = new Server(args[0]);
s.conversazione();
}
}
this is the class which i execute to run the client side:
public class ProvaClient {
public static void main(String[] args) {
Client c = new Client(args[0]);
c.conversazione();
}
}
The code works well if i open two prompt (on the same pc connected in the same network) and do that:
- in one prompt i run server class
- in the other prompt i run the client class
After running client class i insert my localhost and it work well.
The code works well also if i open a prompt on a pc and the other prompt on another pc (but connected in the same network)
- in one prompt (1st pc) i run server class
- in the other prompt (2nd pc) i run the client class
After running client class i insert the IP address (IPV4) of the other machine and it work well.
After this explanation, i ask you, how can i modify the code to make the code working beetween two PCs connected TO DIFFERENT NETWORKS whithout using a phisical server?

multiple messages through the same socket doesn't work

Im working on a simple ftp server, and the client must send multiples messages to the server, and for each message the server send back to the client a anwser. when the client sends one message it works perfectly and the server responds without any problem, for example, when the client sends "USER username" the server send back to the client "password needed".
But when the client sends another message "PASS password" (using the same socket) it doesnt work ! ONLY the first exchange works (for the username), when the first message is sent, the server anwser without any problem, but it block when it want to send the second message (for the password).
please anyone can help me ? thank you !!
here is my code :
#Test
public void testProcessPASS() throws IOException{
Socket socket = new Socket(server.getAddress(), server.getcmdPort());
this.ClientReceiveMessage(socket); // to flush
String cmd = "USER user_test\r\n";
this.ClientSendMessage(socket, cmd);
String anwser = this.ClientReceiveMessage(socket);
assertEquals("Response error.", Constants.MSG_331.replace("\r\n", ""), anwser);
//PROBLEME STARTS HERE :/
String cmd2 = "PASS pass_test\r\n";
this.ClientSendMessage(socket, cmd2);
String anwser2 = this.ClientReceiveMessage(socket);
assertEquals(Constants.MSG_230.replace("\r\n", ""), anwser2);
socket.close();
}
public void ClientSendMessage(Socket skt, String msg) throws IOException{
PrintWriter messageClient = new PrintWriter(new OutputStreamWriter(skt.getOutputStream()),true);
messageClient.println(msg);
messageClient.flush();
}
public String ClientReceiveMessage(Socket skt) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(skt.getInputStream()));
String res = br.readLine() ;
return res;
}
this is the server code :
public class Server implements Runnable {
private ServerSocket cmdserverSocket;
private ServerSocket dataServerSocket;
private boolean running;
public Server() throws IOException {
this.cmdserverSocket = new ServerSocket(1024);
this.dataServerSocket = new ServerSocket(1025);
this.running = false;
}
public boolean isRunning() {
return this.running;
}
public InetAddress getAddress() {
return this.cmdserverSocket.getInetAddress();
}
public int getcmdPort() {
return this.cmdserverSocket.getLocalPort();
}
public int getDataPort() {
return this.dataServerSocket.getLocalPort();
}
public void run() {
// TODO Auto-generated method stub
this.running = true;
System.out.println("server started on port : " + this.getcmdPort());
while (this.running) {
try {
Socket socket = this.cmdserverSocket.accept();
new Thread(new FtpRequest(socket, this.dataServerSocket))
.start();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("server error : " + e.getMessage());
this.running = false;
}
}
}
}
and this is the class that handles client requests and that sends messages to client and running on a new thread :
public class FtpRequest implements Runnable {
private Socket cmdSocket;
private Socket dataSocket;
private BufferedReader cmdBufferedReader;
private DataOutputStream cmdDataOutputStream;
private ServerSocket dataServerSocket;
private boolean anonymous;
private boolean connected;
private String username;
private boolean processRunning;
private String directory;
public FtpRequest(Socket cmds, ServerSocket dts) throws IOException {
this.cmdSocket = cmds;
this.dataServerSocket = dts;
this.cmdBufferedReader = new BufferedReader(new InputStreamReader(
this.cmdSocket.getInputStream()));
this.cmdDataOutputStream = new DataOutputStream(
this.cmdSocket.getOutputStream());
this.anonymous = true;
this.connected = false;
this.username = Constants.ANONYMOUS_USER;
this.processRunning = true;
this.directory = "/home";
}
/**
* send a message on the socket of commands
*
* #param msg
* the msg to send on the socket of commands
* #throws IOException
*/
public void sendMessage(String msg) throws IOException {
System.out.println("FtpRequest sendMessage : " + msg);
PrintWriter messageClient = new PrintWriter(new OutputStreamWriter(
this.cmdDataOutputStream), true);
messageClient.println(msg);
messageClient.flush();
/*
* this.cmdDataOutputStream.writeBytes(msg);
* this.cmdDataOutputStream.flush(); this.cmdSocket.close();
*/
}
public void run() {
// TODO Auto-generated method stub
System.out.println("FtpRequest running ...");
try {
this.sendMessage(Constants.MSG_220); // service ready for new user
this.handleRequest();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // service ready for new user
}
/**
* this method handle the request readen from cmd socket and run the
* required method
*
* #throws IOException
*/
private void handleRequest() throws IOException {
String rqst = this.cmdBufferedReader.readLine();
Request request = new Request(rqst);
System.out.println("FtpRequest handleRequest" + rqst);
switch (request.getType()) {
case USER:
this.processUSER(request);
break;
case PASS:
this.processPASS(request);
break;
default:
this.sendMessage(Constants.MSG_502); // Command not implemented.\r\n
break;
}
/*
* if (this.processRunning = true) this.handleRequest();
*
* else { this.cmdSocket.close(); System.out.println("socket closed ");
* }
*/
}
private void processUSER(Request rqst) throws IOException {
System.out.println("FtpRequest processUSER");
if (rqst.getArgument().equals(Constants.ANONYMOUS_USER)) {
this.sendMessage(Constants.MSG_230); // user loged in
this.connected = true;
this.anonymous = true;
this.username = Constants.ANONYMOUS_USER;
} else if (rqst.getArgument().equals(Constants.USER_TEST)) {
this.sendMessage(Constants.MSG_331); // User name okay, need
// password.\r\n
this.username = Constants.USER_TEST;
} else
this.sendMessage(Constants.MSG_332);
}
private void processPASS(Request rqst) throws IOException {
System.out.println("FtpRequest processPASS");
if (rqst.getArgument().equals(Constants.USER_TEST)
&& rqst.getArgument().equals(Constants.PASS_TEST)) {
this.sendMessage(Constants.MSG_230);
this.connected = true;
this.anonymous = false;
} else
this.sendMessage(Constants.MSG_332); // au cas seulement le mot de
// passe est fourni
}
}
There are some problems with your code.
ClientSendMessage() is using PrintWriter.println(), which outputs a line break. But your input strings already have line breaks on them, so the println() is sending extra line breaks. Also, the line break println() outputs is platform-dependent, whereas FTP uses CRLF specifically. So you should not be using println() at all.
ClientReceiveMessage() does not account for multi-line responses. Per RFC 959, section 4.2 "FTP REPLIES":
A reply is defined to contain the 3-digit code, followed by Space
<SP>, followed by one line of text (where some maximum line length
has been specified), and terminated by the Telnet end-of-line
code. There will be cases however, where the text is longer than
a single line. In these cases the complete text must be bracketed
so the User-process knows when it may stop reading the reply (i.e.
stop processing input on the control connection) and go do other
things. This requires a special format on the first line to
indicate that more than one line is coming, and another on the
last line to designate it as the last. At least one of these must
contain the appropriate reply code to indicate the state of the
transaction. To satisfy all factions, it was decided that both
the first and last line codes should be the same.
Thus the format for multi-line replies is that the first line
will begin with the exact required reply code, followed
immediately by a Hyphen, "-" (also known as Minus), followed by
text. The last line will begin with the same code, followed
immediately by Space <SP>, optionally some text, and the Telnet
end-of-line code.
For example:
123-First line
Second line
234 A line beginning with numbers
123 The last line
The user-process then simply needs to search for the second
occurrence of the same reply code, followed by <SP> (Space), at
the beginning of a line, and ignore all intermediary lines. If
an intermediary line begins with a 3-digit number, the Server
must pad the front to avoid confusion.
The server's initial greeting is likely to be multi-line, but any response to any command can potentially be multi-line, so you need to handle that.
But more importantly, when doing error checking, you need to look at only the 3-digit response code, not the text that accompanies it. Except for a few select commands, like PASV, MLST/MLSD, etc, the text is otherwise arbitrary, the server can send whatever it wants. So you need to ignore the text except for those cases where it is actually needed, or when reporting error messages to the user.
Try something more like this:
private Socket socket;
private BufferedReader br;
#Test
public void testProcessPASS() throws IOException{
socket = new Socket(server.getAddress(), server.getcmdPort());
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.ClientReceiveMessage(220);
this.ClientSendMessage("USER user_test", 331);
this.ClientSendMessage("PASS pass_test", 230);
this.ClientSendMessage("QUIT", 221);
socket.close();
br = null;
socket = null;
}
public int ClientSendMessage(String msg, int ExpectedReplyCode) throws IOException{
Writer bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write(msg);
bw.write("\r\n");
bw.flush();
return ClientReceiveMessage(ExpectedReplyCode);
}
public int ClientReceiveMessage(int ExpectedReplyCode) throws IOException{
String line = br.readLine();
String msgText = msgText.substring(4);
if ((line.length() >= 4) && (line[3] == '-')) {
String endStr = line.substring(0, 2) + " ";
do {
line = br.readLine();
msgText += ("\r\n" + line.substring(4));
}
while (line.substring(0, 3) != endStr);
}
int actualReplyCode = Integer.parseInt(line.substring(0, 2));
assertEquals("Response error. " + msgText, ExpectedReplyCode, actualReplyCode);
// TODO: if the caller wants the msgText for any reason,
// figure out a way to pass it back here...
return actualReplyCode;
}

Having trouble sending one password attempt at a time (Java)

I am trying to do an extra credit assignment for my Java class where we are attempting to hack into a server. The problem I am having right now is only sending one password at a time:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Client
{
private Socket socket;
private PrintWriter out;
private BufferedReader in;
private static int passwordLength;
private static String attempt;
private static int counter = 0;
private static String acceptable = "ABCDEFGHIJKLMNOPQRSTUVWXYXZabcdefghijklmnopqrstuvwxyz0123456789";
public Client()
{
try
{
System.out.println("Connecting to server...");
socket = new Socket("localhost", 58999);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (Exception e)
{
System.out.println("Run the server first.");
}
}
public void close()
{
try
{
socket.close();
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
public String sendPassword(String pass)
{
if (!HUSH) System.out.print("Sending: " + pass);
out.println(pass);
String result = null;
try
{
result = in.readLine();
if (!HUSH)
{
if (result.equals("no"))
System.out.println(" (wrong password)");
else if (result.equals("yes"))
System.out.println(" (CORRECT!)");
}
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
return result;
}
public static boolean HUSH = false;
public static void main(String[] args)
{
Client me = new Client();
//BEGIN YOUR WORK
int length;
HUSH = false; //change this to false for testing
System.out.println("Input character length");
Scanner ui = new Scanner(System.in);
length = ui.nextInt();
Client(length);//set the max length of the password
generate();//pull into the first generate method
me.sendPassword("1234");
me.sendPassword(attempt); //the first password i am trying to break
me.sendPassword("letmein");
me.sendPassword("willthiswork");
// END YOUR WORK
me.close();
}
public static void Client(int max)
{
passwordLength = max;
}
public static void generate()
{
generate(""); //enters generate(String password)
}
static void generate(String password)
{
//base case
if(password.length() == passwordLength)//if password is long enough
System.out.println(++counter + " " + password);
else
for(int x = 0; x < acceptable.length(); x++)
generate(attempt = password + acceptable.charAt(x));
}
}
When I run the code (using the server that is supplied), it runs every possible password combination, but returns 9 (passwordLength number of times) instead of sending say..... A (wrong password) B (wrong password) so on and so forth. I know I need to add something onto my for loop to call it back to main, but I'm not sure how to.

Java: XML object

I'm making simple peer to peer game and I decided to use XML to send information over sockets(example below). But I'm not sure how to send it ? I should simply use ObjectOutputStream.writeObject(obj) and as parameter use object from my example ?
Mainly I'm asking, how does look proper sending XML objects over sockets.
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class SendIPObject {
public static void main(String[] args) throws Exception {
JAXBContext context = JAXBContext.newInstance(IPSender.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Player object = new Player();
object.setID(0);
object.setIP("192.167.211.167");
m.marshal(object, System.out);
}
}
import java.io.Serializable;
abstract public class Player implements Serializable{
private String ip;
private int id;
public String getIP() {
return ip;
}
public int getID() {
return id;
}
public void setIP(String ip) {
this.ip = ip;
}
public void setID(int id) {
this.id = id;
}
}
XML is sent as plain string. So first step would be to create clients that can send and receive from each other strings, e.g. "Hello, world.". Next you need to create an object and using JAXB convert to String and send. Than receive it on other client and using JAXB again. This way you can easily debug what you send and receive. Once you've done it you can try to avoid converting to temporary xml string and use socket streams directly on marshalling and unmarshalling.
I think you shouldn't use ObjectOutputStream because it serializes object to byte array. But you need to "serialize" your object to XML (string) and send it.
Here you can see how can you marshal object to java String: I want to convert an output stream into String object
If the sender and receiver are both java based, you can actually skip the converting to xml back and forth, and send the object over ObjectInputStream. This is essentially an alternative to using xml. You could also use the ObjectInputStream with the String class if you wanted to.
I changed your Player class slightly to to be concrete and have added a toString() method to show what was received on both ends.
Here is how the client looks:
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Player player = new Player("192.168.1.10", 1);
//create connection
Socket sock = new Socket("127.0.0.1", 8080);
//get teh output stream to send in over
ObjectOutputStream cout = new ObjectOutputStream(sock.getOutputStream());
//send it
System.out.println("Sending: "+player.toString());
cout.writeObject(player);
//close connection
sock.close();
System.out.println("Closed");
}
}
Here is how the Server looks:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
try {
System.out.print("\nserver>> ");
// listen for connection from client
Socket sock = serverSocket.accept();
System.out.println("CONNECTION ACCEPTED");
ObjectInputStream sin = new ObjectInputStream(sock.getInputStream());
//read the player in
Player player = (Player) sin.readObject();
System.out.println("from Client>> " + player.toString());
// close the connection
sock.close();
System.out.println("server>> CONNECTION CLOSED");
System.exit(0);
} catch (Exception e) {
}
}
}
}

Categories

Resources