3 * Time-stamp: "2007-10-04 09:53:29 anton"
6 import java
.io
.IOException
;
7 import java
.net
.DatagramPacket
;
8 import java
.net
.DatagramSocket
;
9 import java
.net
.InetAddress
;
10 import java
.net
.SocketException
;
11 import java
.util
.Collection
;
12 import java
.util
.Hashtable
;
17 * @author "Anton Johansson" <anton.johansson@gmail.com>
20 private Hashtable
<InetAddress
, User
> users
;
21 private Hashtable
<String
, Channel
> channels
;
22 private DatagramSocket serverSocket
;
23 private static final byte USERADDED
= 101; // Användare inlagd Användarens namn Sändande klient
24 private static final byte CHANNELCREATED
= 102; // Chatrum skapat Namnet på det nya chatrummet Alla klienter i alla rum
25 private static final byte NAMEONCHANNEL
= 103; // Namn på ett chat-rum Namn Den som frågade efter en lista på rum
26 private static final byte USERJOINEDCHANNEL
= 104; // Ny deltagare i ett rum Deltagarens namn Alla klienter i aktuellt rum
27 private static final byte MESSAGETOALLINCHANNEL
= 105; // Meddelande till alla i rummet Meddelandetext Alla klienter i aktuellt rum
28 private static final byte NAMEONUSER
= 106; // Namn på en av deltagarna i rummet Deltagarens namn Den som frågade efter en lista
29 private static final byte USERLEFTCHANNEL
= 107; // En deltagare har lämnat rummet Deltagarens namn Alla klienter i aktuellt rum
30 private static final byte ERROR
= 108; // Ett fel har uppstått.
31 private static final String SERVER
= "MODERMODEMET";
34 * Creates a new Server instance.
36 * @param serverPort the port the server is listening to
37 * @exception SocketException if an error occurs
38 * @exception IOException if an error occurs
40 public Server(int serverPort
) throws SocketException
, IOException
{
41 this.users
= new Hashtable
<InetAddress
, User
>();
42 this.channels
= new Hashtable
<String
, Channel
>();
43 this.serverSocket
= new DatagramSocket(serverPort
);
45 byte[] sendData
= new byte[1024];
46 byte[] receivedData
= new byte[1024];
48 //checks for new messages from clients
50 DatagramPacket receivePacket
= new DatagramPacket(receivedData
,
53 // receives messages from client
54 serverSocket
.receive(receivePacket
);
55 receivedData
= receivePacket
.getData();
57 int messageType
= receivedData
[0];
58 int messageLength
= receivedData
[1];
59 String message
= new String(receivedData
).substring(2, messageLength
+ 2);
60 InetAddress IPAddress
= receivePacket
.getAddress();
61 int port
= receivePacket
.getPort();
63 User user
= users
.get(IPAddress
);
65 System
.out
.println("=========> New Packet Received <=============");
66 System
.out
.println("Got a request from " + IPAddress
+ ":" + port
);
67 System
.out
.println("Type : " + messageType
);
68 System
.out
.println("Message : " + message
);
73 else if (messageType
!= 1) {
74 System
.out
.println("Got corrupt message from none user");
75 sendMessage(ERROR
, SERVER
,
76 "You are not logged in",
81 if ((messageType
== 1 || messageType
== 2 || messageType
== 4)
82 && (message
== null || message
== "")) {
83 //FIX error error achtung
84 System
.out
.println("Got a request, type " + messageType
+ " with empty message");
85 sendMessage(ERROR
, SERVER
,
86 "You didn't supply enough information",
91 switch (messageType
) {
94 user
= new User(message
, IPAddress
, port
);
95 users
.put(user
.getIPAddress(), user
);
96 sendMessage(USERADDED
, SERVER
,
97 "User " + message
+ " created",
102 if (channels
.get(message
) != null) {
103 System
.out
.println("Tried to create chanel " + message
+ " that already exists");
104 sendMessage(ERROR
, SERVER
,
105 "This channel already exists",
109 channel
= new Channel(message
);
110 channels
.put(message
, channel
);
111 sendMessageToAll(CHANNELCREATED
, SERVER
,
112 user
.getNick() + " created channel \"" + channel
.getName() + "\"");
113 //sendMessage(CHANNELCREATED, SERVER, "Channel " + message + " created", user);
117 if (channels
.isEmpty()) {
119 sendMessage(ERROR
, SERVER
,
120 "There are no channels",
123 catch (IOException e
) {
124 System
.out
.println(e
);
129 Collection
<Channel
> tempChannels
= channels
.values();
130 for (Channel c
: tempChannels
) {
132 sendMessage(USERADDED
, SERVER
, c
.getName(), user
);
134 catch (IOException e
) {
135 System
.out
.println(e
);
141 System
.out
.println(user
.getNick());
142 channel
= joinChannel(message
, user
);
143 sendMessageToChannel(USERJOINEDCHANNEL
, SERVER
,
144 "User " + user
.getNick() + " joined \"" + channel
.getName() + "\"",
148 //message to all in channel
149 if (user
.getChannel() == null) {
150 sendMessage(ERROR
, SERVER
,
151 "You are not in a channel",
155 sendMessageToChannel(MESSAGETOALLINCHANNEL
, user
.getNick(),
156 message
, user
.getChannel());
159 //list users in channel
160 if (user
.getChannel() == null) {
161 sendMessage(ERROR
, SERVER
,
162 "You are not in a channel",
166 channel
= user
.getChannel();
167 //FIX Varför kan jag omdef users här?
168 Collection
<User
> users
= channel
.getUsers();
169 for (User u
: users
) {
170 sendMessage(NAMEONUSER
, SERVER
,
171 "User: " + u
.getNick(),
177 if ((channel
= user
.getChannel()) == null) {
178 sendMessage(ERROR
, SERVER
,
179 "You are not in a channel",
183 user
.joinChannel(null);
184 channel
.leaveUser(user
);
185 sendMessage(USERLEFTCHANNEL
, SERVER
,
186 "You left the channel \"" + channel
.getName() + "\"",
188 sendMessageToChannel(USERLEFTCHANNEL
, SERVER
,
189 "User " + user
.getNick() + " has left this channel",
193 System
.out
.println("Unknown messageType received");
200 * Joins a user to a channel. If there is no such channel on the
201 * server, a new one is created.
203 * @param channelName the name of the channel to join
204 * @param user the user who joins the channel
205 * @return the channel joined and possibly newly created
206 * @exception IOException if an error occurs
208 public Channel
joinChannel(String channelName
, User user
) throws IOException
{
209 Channel channel
= user
.getChannel();
210 if (channel
!= null) {
211 channel
.leaveUser(user
);
212 sendMessageToChannel(USERLEFTCHANNEL
, SERVER
,
213 "User " + user
.getNick() + " has left this channel",
217 channel
= channels
.get(channelName
);
218 if (channel
== null) {
220 channel
= new Channel(channelName
);
221 channels
.put(channelName
, channel
);
222 sendMessageToAll(CHANNELCREATED
, SERVER
,
223 user
.getNick() + " created channel \"" + channel
.getName() + "\"");
226 user
.joinChannel(channel
);
227 channel
.joinUser(user
);
232 * Sends a message to everyone in a Channel
234 * @param messageType the type of the message
235 * @param sender the sender of the message
236 * @param message the message
237 * @param channel the channel to send the message to
238 * @exception IOException if an error occurs
240 public void sendMessageToChannel(byte messageType
, String sender
,
242 Channel channel
) throws IOException
{
243 Collection
<User
> users
= channel
.getUsers();
244 for (User toUser
: users
) {
245 sendMessage(messageType
, sender
, message
, toUser
);
250 * Sends a message to every user connected to this server
252 * @param messageType the type of the message
253 * @param sender the sender of the message
254 * @param message the message
255 * @exception IOException if an error occurs
257 public void sendMessageToAll(byte messageType
, String sender
,
258 String message
) throws IOException
{
259 Collection
<User
> allUsers
= users
.values();
260 for (User toUser
: allUsers
) {
261 sendMessage(messageType
, sender
, message
, toUser
);
266 * Sends a message to a specified IP-Address and port-number. Used
267 * to send messages to users not correctly logged in to the
270 * @param messageType the type of the message
271 * @param sender the sender of the message
272 * @param message the message
273 * @param IPAddress the IP-Address to send the message to
274 * @param port the port-number to send the message to
275 * @exception IOException if an error occurs
277 public void sendMessage(byte messageType
, String sender
,
278 String message
, InetAddress IPAddress
,
279 int port
) throws IOException
{
280 User user
= new User("noNick", IPAddress
, port
);
281 sendMessage(messageType
, sender
, message
, user
);
285 * Sends a message to a specified user.
287 * @param messageType the type of the message
288 * @param sender the sender of the message
289 * @param message the message
290 * @param user the user to send the message to
291 * @exception IOException if an error occurs
293 public void sendMessage(byte messageType
, String sender
,
294 String message
, User user
) throws IOException
{
295 InetAddress IPAddress
= user
.getIPAddress();
296 int port
= user
.getPort();
297 String sendMessage
= "<" + sender
+ "> " + message
;
298 byte[] sendData
= new byte[2 + sendMessage
.length()];
299 sendData
[0] = messageType
;
300 sendData
[1] = (byte) sendMessage
.length();
301 for (int i
= 0, n
= sendMessage
.length(); i
< n
; i
++) {
302 sendData
[i
+2] = (byte) sendMessage
.charAt(i
);
304 System
.out
.println("Sending message of type " + (int) messageType
+ " to " + IPAddress
+ ":" + port
);
305 DatagramPacket sendPacket
= new DatagramPacket(sendData
, sendData
.length
,
307 serverSocket
.send(sendPacket
);
311 * Method to start the server from a command-line. Ex:
312 * $ java Server // Creates a server listening to default port 7877
313 * $ java Server 4444 // Creates a server listening to port 4444
315 * @param args first argument is used to specify which port the
316 * server should listen to
317 * @exception IOException if an error occurs
319 public static void main(String
[] args
) throws IOException
{
320 int serverPort
= 7877;
322 serverPort
= Integer
.parseInt(args
[0]);
324 catch (Exception e
) {
325 System
.out
.println("No port specified");
328 System
.out
.println("Server uses port: " + serverPort
);
329 Server serv
= new Server(serverPort
);