Pwnz
July 23rd, 2010, 21:53
A client is characterized by distributed processing of information between client machines and "servers". Clients make "requests" through a network or networks, and receive "responses" from servers.
In other words a Client displays everything a server requests. The server tells the client what to do, the the cache, holds all the stuff TO display. The client then displays the models on screen as you see them in every-day games. Without the client server, link, there is nothing to be displayed, this is why when a server is down, the client is unable to connect.
A server
A program that responds to client requests, which are generally transmitted over a network
In other words, to put this into RSPS terms, let's say you ban somebody from the client, it must be transmitted and processed in the server files to display a user as banned.
Real Life Server & Clients -
Client Server
TV TV data centers
Computer Screen Computer Tower
Web Browser Websites Files
Section 2- How to create your own clients and Servers
Writing a blocking server and complementary client
by Pwnz
Table of Contents:
[Chapter 1]: What you will need and how to get it
[Chapter 1.1]: Obtaining and installing Eclipse
[Chapter 1.2]: Obtaining and installing the JDK and JRE
[Chapter 1.3]: Starting a project in Eclipse
[Chapter 1.4]: Various operations in Eclipse
[Chapter 2]: Understanding blocking I/O and non-blocking I/O
[Chapter 3]: Writing a basic blocking server socket
[Chapter 3.1]: Understanding buffers and I/OStreams.
[Chapter 3.2]: Writing the server socket itself
[Chapter 3.3]: Handling input and output streams
[Chapter 4]: Writing a complementary client
[Chapter 4.1]: Writing the client
[Chapter 5]: Conclusion
Chapter 1: What you will need and how to get it
In order to accomplish what we need to accomplish, you will need a couple of things. These things are explained in the next chapter.
Chapter 1.1: Obtaining and installing Eclipse
Eclipse, an Integrated-Development-Environment for Java, can be downloaded at the official Eclipse website: Only the registered members can see the link.
In order to extract the archive given on the download page, you will need a freeware program called WinRAR (the unrar package on most Linux systems will suffice). This can be downloaded at: Only the registered members can see the link.
Extract the eclipse folder to C:/Program Files/, or My Documents, or wherever you want it to be. I recommend making a shortcut on your desktop if you can.
Upon the first launch, you will be requested to pick a workspace directory, I just picked My Documents/Eclipse Projects. Check “make default and do not ask again”.
Chapter 1.2: Obtaining and installing the JDK and JRE
Both the JDK and JRE can be downloaded at the official Sun website: Only the registered members can see the link. In the navigation bar, hover over the Downloads tab and click “Java SE”. Download the JDK first if you do not have the JRE installed, as it will automatically install it for you. Installation is pretty self-explanatory, I would presume.
Chapter 1.3: Starting a project in Eclipse
You can start a project in Eclipse by right-clicking the Package Explorer and choosing New → Java Project from the context menus. Just hit finish and you should be presented with the project name, and a “src” (source) directory. The binary (“bin”) directory is not displayed, but it is there.
Chapter 1.4: Various operations in Eclipse
You will need to know how to create classes, enumerations, annotations, interfaces, and packages using Eclipse's context menus. This is achieved by right-clicking the src directory and navigating to New → WHATEVER YOU WANT TO CREATE.
Chapter 2: Understanding blocking I/O and non-blocking I/O
Blocking I/O is a form of Input/Output in which will “block” the other operations in a thread. This means that, if we create a thread for handling ServerSocket connections, our thread would have to wait for a connection before performing any other operations.
Non-blocking I/O, on the other hand, will allow you to process several different I/O operations, without getting stuck on just one. With non-blocking I/O, if an operation becomes idle, it will not delay the tasks of other operations.
Chapter 3: Writing a basic blocking server socket
In this chapter, we will create our very own blocking server socket. This socket will accept a socket connection and respond to various messages.
Chapter 3.1: Understanding buffers and I/OStreams
All of the data that we will send to the client, and vice-versa will be done via Output/Input streams. The classes are exactly that: OutputStream and InputStream. An input/output stream is backed by a buffer, or an array of bytes. Think about this logically, how would we obtain a byte from a buffer?
Code:
byte getByte() {
return buffer[offset++];
}
All bytes are read in a certain order, unless you specify an index like so:
byte getByte(int pos) {
return buffer[pos];
}
Therefore, if a byte order is sent between server → client or vice-versa like so:
______________________
| | | |
| ABC | DEF | GHI |
|_______|_______|_______|
The only possible way (without specifying and index) to read the bytes, is like so:
getByte() - A
getByte() - B
getByte() - C
getByte() - D
getByte() - E
getByte() - F
getByte() - G
getByte() - H
getByte() - I
A sequence of bytes sent from client → server and vice-versa is called a packet (can also be called a frame).
To understand packets/frames, you need to understand how many bytes are in each primitive type:
byte
1
short
2
integer
4
long
8
Each byte is made up of 8 bits. A bit is either a one (on), or a zero (off). For example, one byte could be made up of a bit order like this: 11111111, 00000000, 10101010, 01010101, and so on. Various operations can be performed to the bits behind bytes, however we will cover this in a later book.
Chapter 3.2: Writing the server socket itself
Here we get on to the good part. Luckily for us, the java.net API already has a handy-dandy ServerSocket class for us. We can set up a basic class like so:
import java.net.ServerSocket;
import java.net.Socket;
publicclass BasicServerSocket implements Runnable {
private ServerSocket serverSocket;
}
Now, we have our ServerSocket instance, but what do we do with it? Good question. We will create a class constructor, to avoid using static fields and methods left and right. This class constructor will instantiate the ServerSocket instance and bind it to a port:
public BasicServerSocket() throws Exception {
serverSocket = new ServerSocket(300);
}
In our case, we will bind our socket to port 300.
Now, in order to accept connections, we should probably be doing some processing. We all know that we can do this via threading, like so:
@Override
publicvoid run() {
while (true) {
try {
Socket socket = serverSocket.accept();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The Socket class is in the java.net package. Now, some may know that we need to override a method in a super class, to do so, we will implement the Runnable interface. Our class should now look like this:
import java.net.ServerSocket;
import java.net.Socket;
publicclass BasicServerSocket implements Runnable {
private ServerSocket serverSocket;
public BasicServerSocket() throws Exception {
serverSocket = new ServerSocket(300);
new Thread(this).start();
}
@Override
publicvoid run() {
while (true) {
try {
Socket socket = serverSocket.accept();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Make sure you remember to start the thread if you are not copying and pasting!!!
Chapter 3.3: Handling input/output streams
Now that we have a server socket that will accept incoming connections, we will want to send data back to the client based on the data that it sends us. We can do this via the getInputStream and getOutputStream methods in the socket class. We will create two instances (DataInputStream and DataOutputStream) that will be instantiated with both the input and output streams from the socket. To do so, we can do this:
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
Note that both the DataInputStream and DataOutputStream classes are found in the java.io package.
Now, the client will send us various commands (hi, and quit). The hi command will provoke us to send the client the current time in a UTF-8 representation. The quit command will obviously close the client's socket connection. So, we will use a simple if-else statement:
String command = in.readUTF();
if(command.equalsIgnoreCase("HI")) {
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
out.writeUTF(sdf.format(c.getTime()));
} elseif(command.equalsIgnoreCase("QUIT")) {
socket.close();
}
Now, we read the command from the client, and in return, send it back the current time.
Here is the completed source code for the server (On the next page):
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Calendar;
publicclass BasicServerSocket implements Runnable {
private ServerSocket serverSocket;
public BasicServerSocket() throws Exception {
serverSocket = new ServerSocket(300);
new Thread(this).start();
}
@Override
publicvoid run() {
while (true) {
try {
Socket socket = serverSocket.accept();
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
String command = in.readUTF();
if(command.equalsIgnoreCase("HI")) {
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
out.writeUTF(sdf.format(c.getTime()));
} elseif(command.equalsIgnoreCase("QUIT")) {
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
publicstaticvoid main(String[] args) throws Exception {
new BasicServerSocket();
}
}
Chapter 4: Writing a complementary client
If you have gotten this far without being confused, you already know how to interpret foreign code so that you can understand it. Also, simply based on what I have explained thus far, you already know how to write the client side (If not, the source is on the next page).
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetAddress;
import java.net.Socket;
publicclass BasicClient {
public BasicClient() throws Exception {
Socket s = new Socket(InetAddress.getLocalHost(), 300);
DataInputStream in = new DataInputStream(s.getInputStream());
DataOutputStream out = new DataOutputStream(s.getOutputStream());
out.writeUTF("HI");
String now = in.readUTF();
System.out.println("The date now is: " + now);
out.writeUTF("QUIT");
}
publicstaticvoid main(String[] args) throws Exception {
new BasicClient();
}
}
So, based on what you have learned so far, you should understand that what we are doing is this:
Client → Server
UTF-8 hi
Server → Client
UTF-8 current time
Client → Server
UTF-8 quit
Server closes client connection.
Chapter 5: Conclusion
By now, you should know the following:
The difference between non-blocking and blocking I/O.
What a buffer is and it's rules.
How an input or output stream can help to read/write to/from a buffer.
The composure of a byte.
How many bytes are in a byte, short, integer, and long.
What a packet or frame is and how it can help us send/receive data.
How to set up a basic blocking server socket and client to send/receive data.
In other words a Client displays everything a server requests. The server tells the client what to do, the the cache, holds all the stuff TO display. The client then displays the models on screen as you see them in every-day games. Without the client server, link, there is nothing to be displayed, this is why when a server is down, the client is unable to connect.
A server
A program that responds to client requests, which are generally transmitted over a network
In other words, to put this into RSPS terms, let's say you ban somebody from the client, it must be transmitted and processed in the server files to display a user as banned.
Real Life Server & Clients -
Client Server
TV TV data centers
Computer Screen Computer Tower
Web Browser Websites Files
Section 2- How to create your own clients and Servers
Writing a blocking server and complementary client
by Pwnz
Table of Contents:
[Chapter 1]: What you will need and how to get it
[Chapter 1.1]: Obtaining and installing Eclipse
[Chapter 1.2]: Obtaining and installing the JDK and JRE
[Chapter 1.3]: Starting a project in Eclipse
[Chapter 1.4]: Various operations in Eclipse
[Chapter 2]: Understanding blocking I/O and non-blocking I/O
[Chapter 3]: Writing a basic blocking server socket
[Chapter 3.1]: Understanding buffers and I/OStreams.
[Chapter 3.2]: Writing the server socket itself
[Chapter 3.3]: Handling input and output streams
[Chapter 4]: Writing a complementary client
[Chapter 4.1]: Writing the client
[Chapter 5]: Conclusion
Chapter 1: What you will need and how to get it
In order to accomplish what we need to accomplish, you will need a couple of things. These things are explained in the next chapter.
Chapter 1.1: Obtaining and installing Eclipse
Eclipse, an Integrated-Development-Environment for Java, can be downloaded at the official Eclipse website: Only the registered members can see the link.
In order to extract the archive given on the download page, you will need a freeware program called WinRAR (the unrar package on most Linux systems will suffice). This can be downloaded at: Only the registered members can see the link.
Extract the eclipse folder to C:/Program Files/, or My Documents, or wherever you want it to be. I recommend making a shortcut on your desktop if you can.
Upon the first launch, you will be requested to pick a workspace directory, I just picked My Documents/Eclipse Projects. Check “make default and do not ask again”.
Chapter 1.2: Obtaining and installing the JDK and JRE
Both the JDK and JRE can be downloaded at the official Sun website: Only the registered members can see the link. In the navigation bar, hover over the Downloads tab and click “Java SE”. Download the JDK first if you do not have the JRE installed, as it will automatically install it for you. Installation is pretty self-explanatory, I would presume.
Chapter 1.3: Starting a project in Eclipse
You can start a project in Eclipse by right-clicking the Package Explorer and choosing New → Java Project from the context menus. Just hit finish and you should be presented with the project name, and a “src” (source) directory. The binary (“bin”) directory is not displayed, but it is there.
Chapter 1.4: Various operations in Eclipse
You will need to know how to create classes, enumerations, annotations, interfaces, and packages using Eclipse's context menus. This is achieved by right-clicking the src directory and navigating to New → WHATEVER YOU WANT TO CREATE.
Chapter 2: Understanding blocking I/O and non-blocking I/O
Blocking I/O is a form of Input/Output in which will “block” the other operations in a thread. This means that, if we create a thread for handling ServerSocket connections, our thread would have to wait for a connection before performing any other operations.
Non-blocking I/O, on the other hand, will allow you to process several different I/O operations, without getting stuck on just one. With non-blocking I/O, if an operation becomes idle, it will not delay the tasks of other operations.
Chapter 3: Writing a basic blocking server socket
In this chapter, we will create our very own blocking server socket. This socket will accept a socket connection and respond to various messages.
Chapter 3.1: Understanding buffers and I/OStreams
All of the data that we will send to the client, and vice-versa will be done via Output/Input streams. The classes are exactly that: OutputStream and InputStream. An input/output stream is backed by a buffer, or an array of bytes. Think about this logically, how would we obtain a byte from a buffer?
Code:
byte getByte() {
return buffer[offset++];
}
All bytes are read in a certain order, unless you specify an index like so:
byte getByte(int pos) {
return buffer[pos];
}
Therefore, if a byte order is sent between server → client or vice-versa like so:
______________________
| | | |
| ABC | DEF | GHI |
|_______|_______|_______|
The only possible way (without specifying and index) to read the bytes, is like so:
getByte() - A
getByte() - B
getByte() - C
getByte() - D
getByte() - E
getByte() - F
getByte() - G
getByte() - H
getByte() - I
A sequence of bytes sent from client → server and vice-versa is called a packet (can also be called a frame).
To understand packets/frames, you need to understand how many bytes are in each primitive type:
byte
1
short
2
integer
4
long
8
Each byte is made up of 8 bits. A bit is either a one (on), or a zero (off). For example, one byte could be made up of a bit order like this: 11111111, 00000000, 10101010, 01010101, and so on. Various operations can be performed to the bits behind bytes, however we will cover this in a later book.
Chapter 3.2: Writing the server socket itself
Here we get on to the good part. Luckily for us, the java.net API already has a handy-dandy ServerSocket class for us. We can set up a basic class like so:
import java.net.ServerSocket;
import java.net.Socket;
publicclass BasicServerSocket implements Runnable {
private ServerSocket serverSocket;
}
Now, we have our ServerSocket instance, but what do we do with it? Good question. We will create a class constructor, to avoid using static fields and methods left and right. This class constructor will instantiate the ServerSocket instance and bind it to a port:
public BasicServerSocket() throws Exception {
serverSocket = new ServerSocket(300);
}
In our case, we will bind our socket to port 300.
Now, in order to accept connections, we should probably be doing some processing. We all know that we can do this via threading, like so:
@Override
publicvoid run() {
while (true) {
try {
Socket socket = serverSocket.accept();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The Socket class is in the java.net package. Now, some may know that we need to override a method in a super class, to do so, we will implement the Runnable interface. Our class should now look like this:
import java.net.ServerSocket;
import java.net.Socket;
publicclass BasicServerSocket implements Runnable {
private ServerSocket serverSocket;
public BasicServerSocket() throws Exception {
serverSocket = new ServerSocket(300);
new Thread(this).start();
}
@Override
publicvoid run() {
while (true) {
try {
Socket socket = serverSocket.accept();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Make sure you remember to start the thread if you are not copying and pasting!!!
Chapter 3.3: Handling input/output streams
Now that we have a server socket that will accept incoming connections, we will want to send data back to the client based on the data that it sends us. We can do this via the getInputStream and getOutputStream methods in the socket class. We will create two instances (DataInputStream and DataOutputStream) that will be instantiated with both the input and output streams from the socket. To do so, we can do this:
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
Note that both the DataInputStream and DataOutputStream classes are found in the java.io package.
Now, the client will send us various commands (hi, and quit). The hi command will provoke us to send the client the current time in a UTF-8 representation. The quit command will obviously close the client's socket connection. So, we will use a simple if-else statement:
String command = in.readUTF();
if(command.equalsIgnoreCase("HI")) {
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
out.writeUTF(sdf.format(c.getTime()));
} elseif(command.equalsIgnoreCase("QUIT")) {
socket.close();
}
Now, we read the command from the client, and in return, send it back the current time.
Here is the completed source code for the server (On the next page):
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Calendar;
publicclass BasicServerSocket implements Runnable {
private ServerSocket serverSocket;
public BasicServerSocket() throws Exception {
serverSocket = new ServerSocket(300);
new Thread(this).start();
}
@Override
publicvoid run() {
while (true) {
try {
Socket socket = serverSocket.accept();
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
String command = in.readUTF();
if(command.equalsIgnoreCase("HI")) {
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
out.writeUTF(sdf.format(c.getTime()));
} elseif(command.equalsIgnoreCase("QUIT")) {
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
publicstaticvoid main(String[] args) throws Exception {
new BasicServerSocket();
}
}
Chapter 4: Writing a complementary client
If you have gotten this far without being confused, you already know how to interpret foreign code so that you can understand it. Also, simply based on what I have explained thus far, you already know how to write the client side (If not, the source is on the next page).
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetAddress;
import java.net.Socket;
publicclass BasicClient {
public BasicClient() throws Exception {
Socket s = new Socket(InetAddress.getLocalHost(), 300);
DataInputStream in = new DataInputStream(s.getInputStream());
DataOutputStream out = new DataOutputStream(s.getOutputStream());
out.writeUTF("HI");
String now = in.readUTF();
System.out.println("The date now is: " + now);
out.writeUTF("QUIT");
}
publicstaticvoid main(String[] args) throws Exception {
new BasicClient();
}
}
So, based on what you have learned so far, you should understand that what we are doing is this:
Client → Server
UTF-8 hi
Server → Client
UTF-8 current time
Client → Server
UTF-8 quit
Server closes client connection.
Chapter 5: Conclusion
By now, you should know the following:
The difference between non-blocking and blocking I/O.
What a buffer is and it's rules.
How an input or output stream can help to read/write to/from a buffer.
The composure of a byte.
How many bytes are in a byte, short, integer, and long.
What a packet or frame is and how it can help us send/receive data.
How to set up a basic blocking server socket and client to send/receive data.