I am trying to study a multi-client chat server. As i'm new in Java, I am unable to run this two .java files in Net beans. I have two java projects and put I these files under them. Server project runs successfully but client project shows:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at chatClient.main(chatClient.java:73)
Client Project
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;
class chatClient extends Frame implements Runnable {
Socket soc;
TextField tf;
TextArea ta;
Button btnSend, btnClose;
String sendTo;
String LoginName;
Thread t = null;
DataOutputStream dout;
DataInputStream din;
chatClient(String LoginName, String chatwith) throws Exception {
super(LoginName);
this.LoginName = LoginName;
sendTo = chatwith;
tf = new TextField(50);
ta = new TextArea(50, 50);
btnSend = new Button("Send");
btnClose = new Button("Close");
soc = new Socket("127.0.0.1", 5217);
din = new DataInputStream(soc.getInputStream());
dout = new DataOutputStream(soc.getOutputStream());
dout.writeUTF(LoginName);
t = new Thread(this);
t.start();
}
void setup() {
setSize(600, 400);
setLayout(new GridLayout(2, 1));
add(ta);
Panel p = new Panel();
p.add(tf);
p.add(btnSend);
p.add(btnClose);
add(p);
show();
}
public boolean action(Event e, Object o) {
if (e.arg.equals("Send")) {
try {
dout.writeUTF(sendTo + " " + "DATA" + " " + tf.getText().toString());
ta.append("\n" + LoginName + " Says:" + tf.getText().toString());
tf.setText("");
} catch (Exception ex) {
}
} else if (e.arg.equals("Close")) {
try {
dout.writeUTF(LoginName + " LOGOUT");
System.exit(1);
} catch (Exception ex) {
}
}
return super.action(e, o);
}
public static void main(String args[]) throws Exception {
chatClient Client1 = new chatClient(args[0],args[1]);
Client1.setup();
}
public void run() {
while (true) {
try {
ta.append("\n" + sendTo + " Says :" + din.readUTF());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
Server Project
import java.net.*;
import java.util.*;
import java.io.*;
class chatServer {
static Vector ClientSockets;
static Vector LoginNames;
chatServer() throws Exception {
ServerSocket soc = new ServerSocket(5217);
ClientSockets = new Vector();
LoginNames = new Vector();
while (true) {
Socket CSoc = soc.accept();
AcceptClient obClient = new AcceptClient(CSoc);
}
}
public static void main(String args[]) throws Exception {
chatServer ob = new chatServer();
}
class AcceptClient extends Thread {
Socket ClientSocket;
DataInputStream din;
DataOutputStream dout;
AcceptClient(Socket CSoc) throws Exception {
ClientSocket = CSoc;
din = new DataInputStream(ClientSocket.getInputStream());
dout = new DataOutputStream(ClientSocket.getOutputStream());
String LoginName = din.readUTF();
System.out.println("User Logged In :" + LoginName);
LoginNames.add(LoginName);
ClientSockets.add(ClientSocket);
start();
}
public void run() {
while (true) {
try {
String msgFromClient = new String();
msgFromClient = din.readUTF();
StringTokenizer st = new StringTokenizer(msgFromClient);
String Sendto = st.nextToken();
String MsgType = st.nextToken();
int iCount = 0;
if (MsgType.equals("LOGOUT")) {
for (iCount = 0; iCount < LoginNames.size(); iCount++) {
if (LoginNames.elementAt(iCount).equals(Sendto)) {
LoginNames.removeElementAt(iCount);
ClientSockets.removeElementAt(iCount);
System.out.println("User " + Sendto + " Logged Out ...");
break;
}
}
} else {
String msg = "";
while (st.hasMoreTokens()) {
msg = msg + " " + st.nextToken();
}
for (iCount = 0; iCount < LoginNames.size(); iCount++) {
if (LoginNames.elementAt(iCount).equals(Sendto)) {
Socket tSoc = (Socket) ClientSockets.elementAt(iCount);
DataOutputStream tdout = new DataOutputStream(tSoc.getOutputStream());
tdout.writeUTF(msg);
break;
}
}
if (iCount == LoginNames.size()) {
dout.writeUTF("I am offline");
} else {
}
}
if (MsgType.equals("LOGOUT")) {
break;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
}
Thanks in advance.
If you look at your client's constructor you'll see that it requires two arguments:
chatClient(String LoginName, String chatwith)
a login and with whom to chat.
I think you don't specify them so the following line throws an exception because there aren't any and args is empty:
chatClient Client1 = new chatClient(args[0],args[1]);
The java arguments you pass from the command line are actually an array of String. If you do not type anything into the command line (or the NetBeans equivalent you will get an ArrrayIndexOutOfBoundsException. Therefore you get an exception because you try to pass an array of strings into chatClient method without there actually being any arguments.
Related
I need to implement a program to transfer files. I decided to make it using a chat template I've made about 1 month ago so I would have a chat with file transfer option.
The transfer should follow the following points:
1- Server only keeps a list of all files provided by connected clients (No file are actually located in the server, only their names)
2- Client "1" requests file "A" then:
if file "A" is located ONLY in client "2", then client "2" should send 100% of the file to client "1"
if file "A" is located in client "2" and client "3" also has file "A", then client "2" should send 50% of the file to client "1" and client "3" should send the other 50%.
(if the file is located in 4 clients it should be 25% each....and so it goes...)
I've already managed to make the server find out which client is requesting the file and which clients have it. But now I'm stuck, I don't know how to make the transfer.
Could someone give me an example of how to do it? or point me through the right direction?
[I'm aware my code has some flaws and I will fix it later, right now I need to make the transfer happen before working on fixes, so please, unless it's related, try to focus on that]
Server:
package tor;
import java.util.*;
import java.io.*;
import java.net.*;
public class Server extends Thread {
private String cname;
private Socket client;
public static Vector<PrintStream> clients;
public static Vector<String> clientnames;
public static Vector<String> archives;
public Server(Socket client) {
this.client = client;
}
public static void main(String[] args) {
clients = new Vector<PrintStream>();
clientnames = new Vector<String>();
archives = new Vector<String>();
try {
ServerSocket server = new ServerSocket(2391);
System.out.println("Server Started!!\n");
while (true) {
Socket client = server.accept();
Server s = new Server(client);
s.start();
}
} catch (IOException e) {
System.out.println("Server could not start ");
}
}
#Override
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintStream out = new PrintStream(client.getOutputStream());
cname = in.readLine();
System.out.println(cname + " Connected --- SERVER!");
if (cname == null) {
System.out.println("Unknown Name");
return;
}
clientnames.add(cname);
clients.add(out);
connected(" ********** [", cname, "] Connected! **********");
String arq;
int size = in.read();
System.out.println(size);
for (int i = 0; i < size; i++) {
arq = in.readLine();
archives.add(arq);
}
String msg = in.readLine();
String selected;
while (true) {
while (!(msg).equals("/exit") && !(msg).equals("/Exit") && !(msg).equals("/EXIT")) {
if ((msg).equals("/list") || (msg).equals("/List") || (msg).equals("/list")) {
out.println("-------- Archives List --------");
for (int i = 0; i < archives.size(); i++) {
out.println(i+"- "+archives.get(i));
}
out.println("-------- ******************* --------");
msg = in.readLine();
} else if (msg.equals("/get") || (msg.equals("/GET")) || (msg.equals("/Get"))){
msg = in.readLine();
int gnum = Integer.parseInt(msg);
selected=archives.get(gnum);
returnAll("[", out, "]: ", "idreq");
out.println("1");
reqAll(selected);
// I BELIVE HERE IS THE RIGHT PLACE TO MAKE DE TRANSFER CODE
msg = in.readLine();
} else {
returnAll("[", out, "]: ", msg);
msg = in.readLine();
}
}
msg = in.readLine();
size = Integer.parseInt(msg);
for (int i = 0; i <= size; i++) {
arq = in.readLine();
for(int j=0;j<archives.size();j++) {
if (archives.get(j).equals(arq)) {
archives.remove(j);
}
}
}
returnAll(" ********** [", out, "] disconnected ", " ********** ");
clients.remove(out);
clientnames.remove(cname);
client.close();
break;
}
} catch (IOException e) {
System.out.println("A Client disconnected ");
}
}
// METHOD TO SEND CONNECTION MESSAGE
public void connected(String msg1, String cname, String msg2) throws IOException {
Enumeration<PrintStream> e = clients.elements();
while (e.hasMoreElements()) {
PrintStream message = (PrintStream) e.nextElement();
message.println(msg1 + cname + msg2);
}
}
// METHOD TO RETURN MESSAGE TO ALL CLIENTS
public void returnAll(String msg1, PrintStream saida, String ac, String msg2) throws IOException {
Enumeration<PrintStream> e = clients.elements();
while (e.hasMoreElements()) {
PrintStream message = (PrintStream) e.nextElement();
message.println(msg1 + cname + ac + msg2);
}
}
public void reqAll(String req) throws IOException {
Enumeration<PrintStream> e = clients.elements();
while (e.hasMoreElements()) {
PrintStream message = (PrintStream) e.nextElement();
message.println(req);
}
}
}
Client:
package tor;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Scanner;
public class Client extends Thread {
private Socket con;
private static boolean done = false;
static ArrayList<String> localArq = new ArrayList<String>();
static int c=0;
public Client(Socket s) {
con = s;
}
public static void main(String[] args) {
try {
String ip;
Scanner s = new Scanner(System.in);
System.out.print("Enter Server's IP: ");
ip =s.next();
Socket con = new Socket(ip, 2391);
PrintStream out = new PrintStream(con.getOutputStream());
System.out.println("Connected to Server!");
System.out.print("Enter your Nickname: ");
BufferedReader scan = new BufferedReader(new InputStreamReader(System.in));
String cname = scan.readLine();
out.println(cname);
String dir="C:\\javator\\"+cname;
Thread t = new Client(con);
t.start();
File folder = new File(dir);
folder.mkdir();
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
localArq.add(listOfFiles[i].getName());
}
}
int size=localArq.size();
out.write(size);
for(int i=0;i<size;i++) {
out.println(localArq.get(i));
}
String msg;
while (true) {
System.out.print("");
msg = scan.readLine();
if(msg.equals("/ll")) {
System.out.println("-------- LOCAL LIST --------");
for (int i = 0; i < localArq.size(); i++) {
System.out.println(localArq.get(i));
}
System.out.println("-------- ******************* --------");
msg = scan.readLine();
}else if(msg.equals("/exit") || (msg.equals("/Exit")) || (msg.equals("/EXIT"))) {
out.println(msg);
size=localArq.size();
out.println(size);
for(int i=0;i<size;i++) {
out.println(localArq.get(i));
}
}
else if(msg.equals("/get") || (msg.equals("/GET")) || (msg.equals("/Get"))) {
System.out.println("Chose file's number to /get: ");
c++;
}
if (done == true) {
break;
}
out.println(msg);
}
} catch (UnknownHostException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
#Override
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String rmsg;
String req;
while (true) {
rmsg = in.readLine();
if (rmsg == null) {
System.out.println("Connection Terminated");
break;
}else if(rmsg.substring(rmsg.length() - 5).equals("idreq")) {
req = in.readLine();
for(int i=0;i<localArq.size();i++) { //IDENTIFIES WHO OWNS THE REQUESTED FILE
if(localArq.get(i).equals(req)) {
System.out.println("Owns requested file");
Socket requester = new Socket("192.168.3.114", 2007);
ObjectOutputStream outputr = new ObjectOutputStream(requester.getOutputStream());
ObjectInputStream inputr = new ObjectInputStream(requester.getInputStream());
Object mens= inputr.readObject();
System.out.println(mens);
outputr.writeObject("OWNER FOUND");
}
}
if(c==1) { //IDENTIFIES WHO WANTS THE FILE
rmsg = in.readLine();
c= Integer.parseInt(rmsg);
System.out.println("file: "+req);
ServerSocket peer = new ServerSocket(2007);
System.out.println("OPEN FOR CONNECTIONS\n");
Socket client = peer.accept();
System.out.println("Client connected: " + client.getInetAddress().getHostAddress());
ObjectOutputStream outputo = new ObjectOutputStream(client.getOutputStream());
ObjectInputStream inputo = new ObjectInputStream(client.getInputStream());
outputo.flush();
outputo.writeObject("Connected to requester");
Object mens= inputo.readObject();
System.out.println(mens);
}
}
else {
System.out.println(rmsg);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
done = true;
}
}
I was able to make a transfer between two clients easily with the information provided and a little research on stackOverflow to understand more about out/inputStreams!
This post also helped me a lot: Sending a file with Java Sockets, losing data
next step is the shared transfer
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.
This question already exists:
Scanner issue when using nextLine after nextXXX [duplicate]
Closed 9 years ago.
I am trying to create a java chat and I got this bug: When I use name = scanner.nextLine() my program works apparently fine (but it's not reading any name, if I use System.out.println(name) I get newline), and when I don't use it my pg automaticly connects to server with no name. Can anyone tell me why it;s happening this?
import java.net.*;
import java.util.*;
import java.io.*;
class Cient
{
static String name;
public static void main(String[] args) throws Exception
{
Scanner scanner = new Scanner(System.in);
System.out.print("Adresa serverului si portul : ");//server adress and port
Socket cs = new Socket( scanner.next(), scanner.nextInt() );
DataOutputStream os = new DataOutputStream( cs.getOutputStream());
final DataInputStream is = new DataInputStream( cs.getInputStream());
String st = "";
System.out.println("Va rugam sa va introduceti numele");//get name
name = scanner.nextLine();
Thread T= new Thread(new Runnable()
{
public void run() {
while (true)
{
String s = "";
try
{
s = is.readUTF();
System.out.println(s);
if(s.equals("Intrerupem conexiunea .... Pa!"))//close connexion
{
return;
}
} catch (IOException ex)
{
}
}
}
});
T.start();
while (true)
{
st = scanner.nextLine();
os.writeUTF(st);
if(st.equals("QUIT") || st.equals("EXIT"))
{
return;//stop reading
}
}
}
}
Here is the Server Class, but I dont believe that's important:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.Vector;
public class MyServer
{
Scanner scanner;
Vector<String> users = new Vector<String>();
Vector<HandleClient> clients = new Vector<HandleClient>();
String disconnectedUser = "InvalidUser";//String care imi spune daca un client s-a razgandit la conectare
int PORT;
public Vector<String> getUserList()
{
return users;
}
public void process() throws Exception
{
scanner = new Scanner(System.in);
System.out.println("PORT: ");
PORT = scanner.nextInt();
ServerSocket server = new ServerSocket(PORT);
System.out.println("Server Online...");
while(true)
{
Socket client = server.accept();
HandleClient c = new HandleClient(client);
if(!(c.userName().equals(disconnectedUser)))
{
clients.add(c);
users.add(c.userName());
}
}
}
public static void main(String ... args) throws Exception
{
new MyServer().process();
}
public void broadcast(String user, String message)throws Exception
{
for (HandleClient c : clients)
if (!(c.userName().equals(user)))
{
c.sendMessage(user,message);
}
}
public void twoUsersBroadcast(String fromUser,String toUser, String msg)throws Exception
{
for(HandleClient c : clients)
{
String a = (String) c.userName();
if(a.equals(toUser))
{
c.sendMessage(fromUser,msg);
return ;
}
}
}
public void changeUserName(String actualName,String newName)
{
int i = 0;
for(HandleClient c: clients)
{
if(c.userName().equals(actualName))
{
c.setUserName(newName);
users.set(i,newName);
}
i++;
}
}
boolean validUserName(String name)
{
for(String c : users)
{
if(c.equals(name))
{
return false;
}
}
return true;
}
class HandleClient extends Thread
{
String name = "";
DataInputStream input;
DataOutputStream output;
public String userName()
{
return name;
}
public void setUserName(String name)
{
this.name = name;
}
public void writeError(String message)
{
try
{
output.writeUTF("EROARE: " + message);
}
catch (IOException e)
{
System.out.print(e.getMessage());
}
}
public HandleClient(Socket client)throws Exception
{
input = new DataInputStream(client.getInputStream());
output= new DataOutputStream(client.getOutputStream());
boolean ok = true;
while(ok == true)
{
name = input.readUTF();
if(name.equals("EXIT"))
{
ok = false;
output.writeUTF("Intrerupem conexiunea .... Pa!");
name = "InvalidUser";//User-ul a renuntat la conexiune
}
else
{
if(validUserName(name) == true)
{
ok = false;
}
else
{
output.writeUTF("Numele este deja folosit. Va rugam sa introducet un alt nume sau EXIT in care doriti sa nu va mai conectati");
}
}
}
if("InvalidUser".equals(name))
{
return;
}
start();
}
public void sendMessage(String username,String msg)throws Exception
{
output.writeUTF( username + ": " + msg);
}
public void run()
{
String line;
try
{
boolean ok = true;
output.writeUTF("Introduceti:");
output.writeUTF("LIST pentru a vedea lista de utilizatori");
output.writeUTF("MSG pentru a transmite un mesaj unui anumit utilizator");
output.writeUTF("BCAST pentru a transmite un mesaj tuturor utilizatorilor");
output.writeUTF("NICK pentru a va schimba numele");
output.writeUTF("QUIT pentru a va deconecta de la server");
while(ok == true)
{
line = input.readUTF();
switch(line)
{
case "LIST":
{
Vector<String> users = getUserList();
output.writeUTF("Lista user-ilor este:");
for(String c : users)
{
output.writeUTF(c);
}
break;
}
case "MSG":
{
output.writeUTF("Introduceti numele persoanei careia doriti sa-i trimiteti mesajul");
line = input.readUTF();
if(validUserName(line) == true)
{
writeError("Numele persoanei nu exista");
break;
}
else
{
if(name.equals(line))
{
writeError("Selectati alt user");
break;
}
else
{
output.writeUTF("Introduceti mesajul pe care il aveti de transmis");
String message = input.readUTF();
if((validUserName(line) == false) && !(line.equals(name)))
{
twoUsersBroadcast(name,line,message);
}
break;
}
}
}
case "BCAST":
{
line = input.readUTF();
broadcast(name,line);
break;
}
case "NICK":
{
output.writeUTF("Va rugam sa va introduceti numele dorit");
line = input.readUTF();
if(validUserName(line))
{
changeUserName(name,line);
}
else
{
writeError("Invalid username");
}
break;
}
case "QUIT":
{
output.writeUTF("Intrerupem conexiunea .... Pa!");
clients.remove(this);
users.remove(name);
ok = true;
break;
}
default:
{
writeError("Comanda incorecta");
}
}
}
}
catch(Exception e)
{
System.err.println(e.getMessage());
clients.remove(this);
users.remove(name);
}
}
}
}
After this line:
Socket cs = new Socket( scanner.next(), scanner.nextInt() );
add:
scanner.nextLine();
So together, it would look like:
Socket cs = new Socket( scanner.next(), scanner.nextInt() );
scanner.nextLine();
This is done to swallow the dangling end of line (EOL) token that is not handled by next() or nextInt() and in fact is only handled by nextLine().
I'm making a multiplayer game in java, and I'm really have some issues here. For some reason, my Datagram socket will stop receiving packets set from the client even though according to the console, it recieved them perfectly fine before. I don't know much about networking or programming with sockets, so this has me stumped.
Here's my code:
Server:
package server;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;
import shared.BaseEntity;
import shared.MethodNotOverridenException;
import shared.Packet;
import shared.Player;
public class S_GameLoop implements Runnable{
//Constants
private static final int TICKS_PER_SECOND = 25;
private static final int TICKS_TO_SKIP = 1000 / TICKS_PER_SECOND;
private static final int MAX_FRAMESKIP = 5;
private static final int SPAWN_COORD_X = 50;
private static final int SPAWN_COORD_Y = 50;
private Vector<S_Client> ClientList;
private Map<Integer, BaseEntity> EntityMap;
private AtomicInteger IDGenerator;
private boolean gameIsRunning = true;
private DatagramSocket socket;
byte[] recieveData = new byte[1024];
byte[] prevRecieveData = new byte[1024];
private int port;
private int loops;
public S_GameLoop(int port) {
ClientList = new Vector<S_Client>();
this.port = port;
IDGenerator = new AtomicInteger();
EntityMap = new HashMap<Integer, BaseEntity>();
}
private void Init() throws SocketException {
System.out.println("INIT");
socket = new DatagramSocket(port);
System.out.println("[Server] Create listen server on " + socket.getLocalAddress().getHostAddress() + " on port " + socket.getLocalPort());
socket.setSoTimeout(0);
}
private void Running() {
System.out.println("S_GameLoop staring");
long nextGameTick = System.currentTimeMillis();
DatagramPacket recievePacket = new DatagramPacket(recieveData, recieveData.length);
//GameLoop goes here
while(gameIsRunning) {
loops = 0;
//Receive the data
try {
socket.receive(recievePacket);
} catch (IOException e1) {
e1.printStackTrace();
}
while(System.currentTimeMillis() > nextGameTick && loops < MAX_FRAMESKIP) {
try {
Update(recievePacket);
} catch (MethodNotOverridenException | IOException e) {
System.err.println(e);
}
nextGameTick += TICKS_TO_SKIP;
loops++;
}
nextGameTick += TICKS_TO_SKIP;
loops++;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void Update(DatagramPacket recievePacket) throws IOException, MethodNotOverridenException {
if(prevRecieveData != recieveData) {
parseData(formatData(recievePacket.getData()), recievePacket);
prevRecieveData = recieveData;
} else {
return;
}
}
public static Packet formatData(byte[] data) {
try {
if(data[1] == 0);
String tag = new String(Arrays.copyOfRange(data, 1, 8));
System.out.println("[Server] Recieved packet " + data[0] + " " + new String(tag));
return new Packet(data[0],tag.getBytes(), Arrays.copyOfRange(data, 8, data.length));
} catch (ArrayIndexOutOfBoundsException e) {
return new Packet((byte)0, new byte[0], new byte[0]);
}
}
private void parseData(Packet p, DatagramPacket recievePacket) throws IOException, MethodNotOverridenException {
if(p.getTag() == new byte[0]) {
System.out.println("[Server] Recieved NULL packet");
return;
}
switch (p.getTagAsString()) {
case "LGN_RQS": System.out.println("[Server] Login Request Recieved");
//Login was accepted
//Create a Client ref, and add it to the vector
S_Client newClient = new S_Client(recievePacket.getAddress(), recievePacket.getPort());
ClientList.add(newClient);
//Create a player and add it to Entity list
Player newPlayer = new Player(IDGenerator.getAndIncrement(), ClientList.indexOf(newClient));
EntityMap.put(newPlayer.getEntID(), newPlayer);
System.out.println("[Server] Created new Player with EID " + newPlayer.getEntID() + " and CID " + newPlayer.getCID());
//Send reply to Client that is logging in
sendData(new Packet((byte)2, "LGN_ACP".getBytes(), ("CID;" + ClientList.indexOf(newClient) + ";EID;" + newPlayer.getEntID()).getBytes()).getBytes(), newClient.getIp(), newClient.getPort());
//New Entity was created
//sendData(newPlayer.onCreate(this));
break;
case "HND_SHK": System.out.println("[Server] Handshake Recieved");
String fdata = new String(p.getData());
String[] data = fdata.split(";");
//Get client by client ID
S_Client c = ClientList.get(Integer.parseInt(data[1]));
c.setUsername(data[3]);
System.out.println("[Server] Set Client " + data[1] + "'s username to " + data[3]);
//Now spawn the player
sendData(new Packet((byte)9, "PLR_SPW".getBytes(), ("CID;" + data[1] + ";X;" + SPAWN_COORD_X + ";Y;" + SPAWN_COORD_Y).getBytes()).getBytes());
break;
}
}
public String[] byteArrayToStringArray(byte[] b) {
String fdata = new String(b);
return fdata.split(";");
}
public void createEntity(BaseEntity be) throws MethodNotOverridenException, IOException {
int ID = IDGenerator.incrementAndGet();
be.setEntID(ID);
EntityMap.put(ID, be);
sendData(be.onCreate(this));
}
public void sendData(byte[] sendData, InetAddress IP, int port) throws IOException {
System.out.println("[Server] Send packet " + sendData[0] + " " + new String(Arrays.copyOfRange(sendData, 1, 8)));
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IP, port);
socket.send(sendPacket);
}
public void sendData(byte[] sendData) throws IOException {
for (S_Client entry : ClientList) {
sendData(sendData, entry.getIp(), entry.getPort());
}
}
#Override
public void run() {
try {
Init();
Running();
} catch (SocketException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
}
}
Client:
package client;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.Arrays;
import java.util.Vector;
import shared.BaseEntity;
import shared.Packet;
import shared.Player;
public class C_GameLoop {
//How fast should the game update?
private static final int TICKS_PER_SECOND = 25;
//How many ticks should be skipped in order to run it at that speed?
//If it runs faster, then the Render() will be called more often
private static final int TICKS_TO_SKIP = 1000 / TICKS_PER_SECOND;
//How many times should you skip rendering, if you have to?
private static final int MAX_FRAMESKIP = 5;
RenderCanvas rc;
InetAddress ServerIP;
private DatagramSocket socket;
private int port;
private boolean connectedToServer = false;
private boolean waitForData = false;
private String username = "Dummy";
byte[] sendPacket;
Vector<BaseEntity> RenderList;
Player player;
int fps = 0;
public C_GameLoop(RenderCanvas rc){
this.rc = rc;
RenderList = new Vector<BaseEntity>();
}
public boolean Connect(InetAddress ServerIP, int port) throws IOException {
this.port = port;
this.ServerIP = ServerIP;
socket = new DatagramSocket();
socket.setSoTimeout(4000);
DatagramPacket recieveData = new DatagramPacket(new byte[1024], new byte[1024].length);
System.out.println("[Client] Connecting to: " + ServerIP.getHostAddress() + ":" + port);
//Send a login request
sendData(new Packet((byte)1, "LGN_RQS".getBytes()).getBytes());
int retries = 0;
//Start the connect loop
while(!connectedToServer) {
try {
socket.receive(recieveData);
waitForData = false;
parseData(formatData(recieveData.getData()));
//recieveData.setData(new Packet((byte)0, new byte[0], new byte[0]).getBytes());
} catch (SocketTimeoutException e) {
if(waitForData = true && retries <= 4) {
System.out.println("[Client] Failed to recieve response from server, retrying");
parseData(formatData(recieveData.getData()));
retries++;
} else {
System.out.println("[Client] Failed to Connect to the server!");
return false;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
public void sendData(byte[] data) throws IOException {
System.out.println("[Client] Sent packet " + data[0] + " " + new String(Arrays.copyOfRange(data, 1, 8)));
DatagramPacket sendPacket = new DatagramPacket(data, data.length, ServerIP, port);
socket.send(sendPacket);
waitForData = true;
}
private void parseData(Packet p) throws IOException {
switch (p.getTagAsString()) {
case "LGN_ACP": System.out.println("[Client] Login Accepted");
//Get the data needed to create a new player from the packet
String fdata = new String(p.getData());
String[] data = fdata.split(";");
Player player = new Player(Integer.parseInt(data[1]), Integer.parseInt(data[3].trim()));
//Add it to the render list
this.player = player;
rc.getCamera().addDrawableEntity(player);
System.out.println("[Client] Player created with CID " + data[1] + " and EID " + data[3]);
//Send the handshake
System.out.println("[Client] Finshing Handshake...");
sendData(new Packet((byte)4, "HND_SHK".getBytes(), ("CID;" + player.getCID() + ";Username;" + username).getBytes()).getBytes());
break;
case "PLR_SPW": System.out.println("[Client] Spawn Recieved");
//Get the coords
String[] spawn_data = byteArrayToStringArray(p.getData());
this.player.setX(Integer.parseInt(spawn_data[3]));
this.player.setY(Integer.parseInt(spawn_data[5].trim()));
sendData(new Packet((byte)0, "KEP_ALV".getBytes()).getBytes());
break;
}
}
public String[] byteArrayToStringArray(byte[] b) {
String fdata = new String(b);
return fdata.split(";");
}
/*
* Formats data into a packet
*/
public static Packet formatData(byte[] data) {
try {
if(data[1] == 0);
String tag = new String(Arrays.copyOfRange(data, 1, 8));
System.out.println("[Client] Recieved packet " + data[0] + " " + new String(tag));
return new Packet(data[0],tag.getBytes(), Arrays.copyOfRange(data, 8, data.length));
} catch (ArrayIndexOutOfBoundsException e) {
return new Packet((byte)0, new byte[0], new byte[0]);
}
}
}
Console output when running code:
INIT
[Server] Create listen server on 0.0.0.0 on port 4334
S_GameLoop staring
[Client] Connecting to: 127.0.0.1:4334
[Client] Sent packet 1 LGN_RQS
[Server] Recieved packet 1 LGN_RQS
[Server] Login Request Recieved
[Server] Created new Player with EID 0 and CID 0
[Server] Send packet 2 LGN_ACP
[Client] Recieved packet 2 LGN_ACP
[Client] Login Accepted
[Client] Player created with CID 0 and EID 0
[Client] Finshing Handshake...
[Client] Sent packet 4 HND_SHK
[Client] Failed to recieve response from server, retrying
(Same lines as previous 6 just repeat 4 times)
[Client] Failed to Connect to the server!
Any Ideas?
It looks like your Server class is designed to be used as the Runnable of some worker thread.
I suspect that the problem is that the run() method is dying due to an uncaught exception, and that the worker thread is simply terminating.
I recommend that you configure a default uncaught exception handler to (at least) log the stack trace for the fatal exception. Refer to the Thread javadocs for details.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class Draw extends JFrame {
/*
* Socket stuff
*/
static String host;
static int port;
static int localport;
DatagramSocket ds;
Socket socket;
Draw d;
Paper p = new Paper(ds);
public Draw(int localport, String host, int port) {
d = this;
this.localport = localport;
this.host = host;
this.port = port;
try {
ds = new DatagramSocket(localport);
InetAddress ia = InetAddress.getByName(host);
System.out.println("Attempting to connect DatagramSocket. Local port "
+ localport + " , foreign host " + host + ", foreign port " + port + "...");
ds.connect(ia, port);
System.out.println("Success, ds.localport: " + ds.getLocalPort()
+ ", ds.port: " + ds.getPort() + ", address: " + ds.getInetAddress());
Reciever r = new Reciever(ds);
r.start();
} catch (Exception e) {
e.printStackTrace();
}
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().add(p, BorderLayout.CENTER);
setSize(640, 480);
setVisible(true);
}
public static void main(String[] args) {
int x = 0;
for (String s : args){
if (x==0){
localport = Integer.parseInt(s);
x++;
}
else if (x==1){
host = s;
x++;
}
else if (x==2){
port = Integer.parseInt(s);
}
}
Draw d = new Draw(localport, host, port);
}
}
class Paper extends JPanel {
DatagramSocket ds;
private HashSet hs = new HashSet();
public Paper(DatagramSocket ds) {
this.ds=ds;
setBackground(Color.white);
addMouseListener(new L1(ds));
addMouseMotionListener(new L2());
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
Iterator i = hs.iterator();
while(i.hasNext()) {
Point p = (Point)i.next();
g.fillOval(p.x, p.y, 2, 2);
}
}
private void addPoint(Point p) {
hs.add(p);
repaint();
}
class L1 extends MouseAdapter {
DatagramSocket ds;
public L1(DatagramSocket ds){
this.ds=ds;
}
public void mousePressed(MouseEvent me) {
addPoint(me.getPoint());
Point p = me.getPoint();
String message = Integer.toString(p.x) + " " + Integer.toString(p.y);
System.out.println(message);
try{
byte[] data = message.getBytes("UTF-8");
//InetAddress ia = InetAddress.getByName(ds.host);
String convertedMessage = new String(data, "UTF-8");
System.out.println("The converted string is " + convertedMessage);
DatagramPacket dp = new DatagramPacket(data, data.length);
System.out.println(ds.getPort());
//System.out.println(message);
//System.out.println(ds.toString());
//ds.send(dp);
/*System.out.println("2Sending a packet containing data: " +data +" to "
+ ia + ":" + d.port + "...");*/
} catch (Exception e){
e.printStackTrace();
}
}
}
class L2 extends MouseMotionAdapter {
public void mouseDragged(MouseEvent me) {
addPoint(me.getPoint());
Point p = me.getPoint();
String message = Integer.toString(p.x) + " " + Integer.toString(p.y);
//System.out.println(message);
}
}
}
class Reciever extends Thread{
DatagramSocket ds;
byte[] buffer;
Reciever(DatagramSocket ds){
this.ds = ds;
buffer = new byte[65507];
}
public void run(){
try {
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while(true){
try {
ds.receive(packet);
String s = new String(packet.getData());
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
You do this:
DatagramSocket ds;
Socket socket;
Draw d;
Paper p = new Paper(ds);
Here, ds is uninitialized, thus null. Paper passes it to L1, thus the ds in L1 is also null.
Well, you've presented quite a mess of code there, but you've got this:
DatagramSocket ds;
Socket socket;
Draw d;
Paper p = new Paper(ds);
The default value for reference type fields is null, so you're effectively calling
new Paper(null)
That will then end up calling
new L1(null)
which is why calling ds.getPort() in L1 is throwing an exception.
Note that the value of the variable is being passed in each case - it's not like the ds within L1 is associated with the ds field in the Draw class.
Without looking in a lot more detail, it's hard to suggest an easy fix - but it's likely to involve waiting until you've created the DatagramSocket before you create the Paper.
When you declare Paper p = new Paper(ds); it initializes the Paper with a null DatagramSocket.
I think what you want to do is to change that line to Paper p; then right after ds = new DatagramSocket(localport); add p = new Paper(ds);
Just a heads up in case you're wondering, a common misconception in Java is that: if you assign new Paper(ds); and you later change ds (not any of its instance variables, you actually change the whole of ds as in: ds = new something), reference manipulation in Java does not mean the instance of ds initially used in paper is changed.