Commit 77176d9b80331d81b356ba95c063e7dcfc724d54
1 parent
8d957e00
git-svn-id: svn://imanolbarba.net/PAD@27 c2ee353e-ed0d-4329-bf56-03aec153487f
Showing
16 changed files
with
294 additions
and
151 deletions
JChatClient/bin/client
No preview for this file type
JChatClient/src/Socket.cpp
... | ... | @@ -6,11 +6,6 @@ |
6 | 6 | * En este fichero se implementan los métodos de la clase Socket definidos en Socket.h |
7 | 7 | */ |
8 | 8 | #include "Socket.h" |
9 | -#include "SocketException.h" | |
10 | -#include <sstream> | |
11 | -#include <strings.h> | |
12 | -#include <cstdlib> | |
13 | -#include <netinet/tcp.h> | |
14 | 9 | |
15 | 10 | using namespace std; |
16 | 11 | |
... | ... | @@ -149,8 +144,11 @@ const Socket& Socket::operator << ( const std::string& text) |
149 | 144 | } |
150 | 145 | sstream << length; |
151 | 146 | string len = sstream.str(); |
152 | - Send(len.c_str(), len.length()+1); | |
153 | - Send(text.c_str(), text.length()); | |
147 | + char* msg = new char[len.length() + text.length() + 1]; | |
148 | + strcpy(msg,len.c_str()); | |
149 | + strcpy(msg+len.length()+1,text.c_str()); | |
150 | + Send(msg, text.length() + len.length() + 1); | |
151 | + delete[] msg; | |
154 | 152 | return *this; |
155 | 153 | } |
156 | 154 | ... | ... |
JChatClient/src/client.cpp
... | ... | @@ -25,13 +25,6 @@ void exitClient(int signal/*!<Parámetro que captura el signal recibido*/) |
25 | 25 | |
26 | 26 | void killThread(thread_args *t_arg) |
27 | 27 | { |
28 | - (t_arg->s)->Close(); | |
29 | - pthread_mutex_lock(t_arg->mutex); | |
30 | - if(t_arg->s != 0) | |
31 | - { | |
32 | - delete t_arg->s; | |
33 | - t_arg->s = 0; | |
34 | - } | |
35 | 28 | if(t_arg != 0) |
36 | 29 | { |
37 | 30 | delete t_arg; |
... | ... | @@ -42,42 +35,69 @@ void killThread(thread_args *t_arg) |
42 | 35 | |
43 | 36 | bool connect(Socket& s) |
44 | 37 | { |
45 | - string host, nick; | |
38 | + string host, nick, response; | |
46 | 39 | int port; |
47 | 40 | /*cout << "Hostname: "; |
48 | - cin >> host; | |
41 | + getline(cin,host); | |
49 | 42 | cout << "Port: "; |
50 | 43 | cin >> port;*/ |
51 | 44 | cout << "Nickname: "; |
52 | - cin >> nick; | |
53 | - cin.ignore(); | |
45 | + getline(cin,nick); | |
54 | 46 | host = "localhost"; |
55 | 47 | port = 3001; |
56 | 48 | |
57 | 49 | try |
58 | 50 | { |
51 | + s.Create(); | |
59 | 52 | s.Connect(host,port); |
60 | 53 | cout << "Connected" << endl; |
61 | 54 | connected = true; |
62 | 55 | s << nick; |
56 | + s >> response; | |
57 | + while(response == "CHATNICKINVALID") | |
58 | + { | |
59 | + cout << "Spaces not allowed in nicknames, please enter another nickname: "; | |
60 | + getline(cin,nick); | |
61 | + s << nick; | |
62 | + s >> response; | |
63 | + } | |
64 | + while(response == "CHATNICKEXIST") | |
65 | + { | |
66 | + cout << "Nickname in use, please enter another nickname: "; | |
67 | + getline(cin,nick); | |
68 | + s << nick; | |
69 | + s >> response; | |
70 | + } | |
71 | + while(response == "CHATFULL") | |
72 | + { | |
73 | + cout << "Chatroom is full, please wait..." << endl; | |
74 | + s >> response; | |
75 | + } | |
76 | + if(response != "CHATOK") | |
77 | + { | |
78 | + cout << "Error: " << response << endl; | |
79 | + return false; | |
80 | + } | |
63 | 81 | } |
64 | 82 | catch(SocketException& e) |
65 | 83 | { |
66 | 84 | cout << e.description() << endl; |
85 | + exit(-1); | |
67 | 86 | } |
87 | + return true; | |
68 | 88 | } |
69 | 89 | |
70 | 90 | void* sendThread(void* args) |
71 | 91 | { |
72 | 92 | string send; |
73 | 93 | struct thread_args *t_arg = (struct thread_args*)args; |
74 | - while(true) | |
94 | + while(connected) | |
75 | 95 | { |
76 | 96 | cout << "> "; |
77 | 97 | getline(cin,send); |
78 | 98 | if(cin.eof()) |
79 | 99 | { |
80 | - send = "/disconnect"; | |
100 | + send = "/exit"; | |
81 | 101 | } |
82 | 102 | try |
83 | 103 | { |
... | ... | @@ -90,9 +110,6 @@ void* sendThread(void* args) |
90 | 110 | catch(SocketException& e) |
91 | 111 | { |
92 | 112 | cout << e.description() << endl; |
93 | - cout << "Exiting" << endl; | |
94 | - (t_arg->s)->Close(); | |
95 | - exit(-1); | |
96 | 113 | } |
97 | 114 | } |
98 | 115 | killThread(t_arg); |
... | ... | @@ -104,11 +121,20 @@ void* recvThread(void* args) |
104 | 121 | struct thread_args *t_arg = (struct thread_args*)args; |
105 | 122 | while(true) |
106 | 123 | { |
107 | - *(t_arg->s) >> recv; | |
124 | + try | |
125 | + { | |
126 | + *(t_arg->s) >> recv; | |
127 | + } | |
128 | + catch(SocketException &e) | |
129 | + { | |
130 | + connected = false; | |
131 | + cout << e.description() << endl; | |
132 | + (t_arg->s)->Close(); | |
133 | + break; | |
134 | + } | |
108 | 135 | if(recv == "DISC_OK") |
109 | 136 | { |
110 | 137 | cout << "Disconnecting" << endl; |
111 | - (t_arg->s)->Close(); | |
112 | 138 | connected = false; |
113 | 139 | pthread_cond_signal(t_arg->condition); |
114 | 140 | break; |
... | ... | @@ -116,7 +142,6 @@ void* recvThread(void* args) |
116 | 142 | else if(recv == "EXIT_OK") |
117 | 143 | { |
118 | 144 | cout << "Exiting" << endl; |
119 | - (t_arg->s)->Close(); | |
120 | 145 | connected = false; |
121 | 146 | finished = true; |
122 | 147 | pthread_cond_signal(t_arg->condition); |
... | ... | @@ -144,10 +169,15 @@ int main() |
144 | 169 | thread_args *sArgs = new thread_args; |
145 | 170 | thread_args *rArgs = new thread_args; |
146 | 171 | pthread_t recv, send; |
147 | - s.Create(); | |
172 | + pthread_attr_t attr; | |
173 | + pthread_attr_init(&attr); | |
174 | + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); | |
148 | 175 | while (!finished) |
149 | 176 | { |
150 | - connect(s); | |
177 | + if(!connect(s)) | |
178 | + { | |
179 | + exit(-1); | |
180 | + } | |
151 | 181 | pthread_mutex_lock(&mutex); |
152 | 182 | sArgs->mutex = &mutex; |
153 | 183 | sArgs->condition = &condition; |
... | ... | @@ -157,14 +187,17 @@ int main() |
157 | 187 | rArgs->condition = &condition; |
158 | 188 | rArgs->s = &s; |
159 | 189 | |
160 | - pthread_create(&send,NULL,sendThread,(void *)sArgs); | |
161 | - pthread_create(&recv,NULL,recvThread,(void *)rArgs); | |
190 | + pthread_create(&send,&attr,sendThread,(void *)sArgs); | |
191 | + pthread_create(&recv,&attr,recvThread,(void *)rArgs); | |
162 | 192 | |
163 | 193 | while(connected) |
164 | 194 | { |
165 | 195 | pthread_cond_wait(&condition,&mutex); |
166 | 196 | } |
167 | 197 | pthread_mutex_unlock(&mutex); |
198 | + pthread_join(recv,NULL); | |
199 | + pthread_join(send,NULL); | |
200 | + s.Close(); | |
168 | 201 | } |
169 | 202 | pthread_cond_destroy(&condition); |
170 | 203 | pthread_mutex_destroy(&mutex); |
... | ... | @@ -172,7 +205,5 @@ int main() |
172 | 205 | |
173 | 206 | /* TODO |
174 | 207 | * |
175 | - * disconnecting causes some real shit | |
176 | - * list nicks | |
177 | - * unicast message | |
208 | + * CTRL+C | |
178 | 209 | */ |
179 | 210 | \ No newline at end of file | ... | ... |
JChatClient/src/include/Socket.h
... | ... | @@ -9,13 +9,17 @@ |
9 | 9 | #define SOCKET_H_ |
10 | 10 | |
11 | 11 | #include <iostream> |
12 | +#include <sstream> | |
13 | +#include "SocketException.h" | |
12 | 14 | #include <sys/socket.h> |
15 | +#include <sys/types.h> | |
13 | 16 | #include <netinet/in.h> |
17 | +#include <netinet/tcp.h> | |
14 | 18 | #include <arpa/inet.h> |
15 | 19 | #include <netdb.h> |
16 | -#include <string> | |
17 | -#include <sys/types.h> | |
18 | 20 | #include <unistd.h> |
21 | +#include <cstdlib> | |
22 | +#include <cstring> | |
19 | 23 | |
20 | 24 | using namespace std; |
21 | 25 | ... | ... |
JChatServer/bin/pad/prac2/ChatException.class
0 → 100644
No preview for this file type
JChatServer/bin/pad/prac2/Connection.class
No preview for this file type
JChatServer/bin/pad/prac2/JChat$1.class
0 → 100644
No preview for this file type
JChatServer/bin/pad/prac2/MyServerSocket.class
No preview for this file type
JChatServer/bin/pad/prac2/MySocket.class
No preview for this file type
JChatServer/bin/pad/prac2/Server.class
No preview for this file type
JChatServer/src/pad/prac2/ChatException.java
0 → 100644
1 | +package pad.prac2; | |
2 | + | |
3 | +public class ChatException extends Exception | |
4 | +{ | |
5 | + | |
6 | + /** | |
7 | + * | |
8 | + */ | |
9 | + private static final long serialVersionUID = 2263415822589627234L; | |
10 | + | |
11 | + public ChatException() | |
12 | + { | |
13 | + super(); | |
14 | + } | |
15 | + | |
16 | + public ChatException(String message) | |
17 | + { | |
18 | + super(message); | |
19 | + } | |
20 | + | |
21 | +} | ... | ... |
JChatServer/src/pad/prac2/Connection.java
... | ... | @@ -15,11 +15,6 @@ public class Connection extends Thread |
15 | 15 | sleep = true; |
16 | 16 | } |
17 | 17 | |
18 | - public void sendMessage(String message) throws IOException | |
19 | - { | |
20 | - socket.sendMsg(message); | |
21 | - } | |
22 | - | |
23 | 18 | public void awake() |
24 | 19 | { |
25 | 20 | synchronized(this) |
... | ... | @@ -32,9 +27,12 @@ public class Connection extends Thread |
32 | 27 | public void finish() |
33 | 28 | { |
34 | 29 | kill = true; |
35 | - sleep = false; | |
30 | + if(sleep) | |
31 | + { | |
32 | + sleep = false; | |
33 | + notify(); | |
34 | + } | |
36 | 35 | socket.close(); |
37 | - this.notify(); | |
38 | 36 | } |
39 | 37 | |
40 | 38 | public void setSock(MySocket s) |
... | ... | @@ -42,6 +40,11 @@ public class Connection extends Thread |
42 | 40 | socket = s; |
43 | 41 | } |
44 | 42 | |
43 | + public void sendMessage(String message) throws IOException | |
44 | + { | |
45 | + socket.sendMsg(message); | |
46 | + } | |
47 | + | |
45 | 48 | public void run() |
46 | 49 | { |
47 | 50 | while(!kill) |
... | ... | @@ -60,45 +63,88 @@ public class Connection extends Thread |
60 | 63 | e.printStackTrace(); |
61 | 64 | } |
62 | 65 | } |
63 | - String str = socket.recvMsg(); | |
64 | - serv.addToChatroom(this, str); | |
65 | 66 | if(!kill) |
66 | 67 | { |
67 | - while(true) | |
68 | + String str; | |
69 | + try | |
68 | 70 | { |
69 | 71 | str = socket.recvMsg(); |
70 | - if(str != null) | |
72 | + while(str.contains(" ")) | |
71 | 73 | { |
72 | - try | |
74 | + socket.sendMsg("CHATNICKINVALID"); | |
75 | + str = socket.recvMsg(); | |
76 | + } | |
77 | + while(serv.isOnline(str)) | |
78 | + { | |
79 | + socket.sendMsg("CHATNICKEXIST"); | |
80 | + str = socket.recvMsg(); | |
81 | + } | |
82 | + socket.sendMsg("CHATOK"); | |
83 | + serv.addToChatroom(this, str); | |
84 | + } | |
85 | + catch (IOException e) | |
86 | + { | |
87 | + if(!kill) | |
88 | + { | |
89 | + System.out.println("TCP: Communication with client failed while entering chatroom"); | |
90 | + sleep = true; | |
91 | + serv.finishWorker(this); | |
92 | + } | |
93 | + continue; | |
94 | + } | |
95 | + while(true) | |
96 | + { | |
97 | + try | |
98 | + { | |
99 | + str = ""; | |
100 | + str = socket.recvMsg(); | |
101 | + if(str.equals("/disconnect")) | |
73 | 102 | { |
74 | - if(str.equals("/disconnect")) | |
75 | - { | |
76 | - socket.sendMsg("DISC_OK"); | |
77 | - kill = true; | |
78 | - System.out.println(serv.getNickname(this) + " disconnected"); | |
79 | - break; | |
80 | - } | |
81 | - else if(str.equals("/exit")) | |
103 | + socket.sendMsg("DISC_OK"); | |
104 | + System.out.println(serv.getNickname(this) + " disconnected"); | |
105 | + break; | |
106 | + } | |
107 | + else if(str.equals("/exit")) | |
108 | + { | |
109 | + socket.sendMsg("EXIT_OK"); | |
110 | + System.out.println(serv.getNickname(this) + " disconnected"); | |
111 | + break; | |
112 | + } | |
113 | + else if(str.equals("/who")) | |
114 | + { | |
115 | + socket.sendMsg(serv.listOnline()); | |
116 | + } | |
117 | + else if(str.startsWith("@")) | |
118 | + { | |
119 | + try | |
82 | 120 | { |
83 | - socket.sendMsg("EXIT_OK"); | |
84 | - kill = true; | |
85 | - System.out.println(serv.getNickname(this) + " disconnected"); | |
86 | - break; | |
121 | + if(!str.contains(" ")) | |
122 | + { | |
123 | + serv.sendTo(this,str.substring(1),""); | |
124 | + } | |
125 | + else | |
126 | + { | |
127 | + serv.sendTo(this,str.substring(1,str.indexOf(' ')),str.substring(str.indexOf(' ')+1)); | |
128 | + } | |
87 | 129 | } |
88 | - else | |
130 | + catch(ChatException cE) | |
89 | 131 | { |
90 | - System.out.println("FROM " + serv.getNickname(this) + ": " + str); | |
91 | - serv.sendToChat(this,str); | |
132 | + socket.sendMsg(cE.getMessage()); | |
92 | 133 | } |
93 | 134 | } |
94 | - catch(IOException ioExc) | |
135 | + else if(str.equals("")) | |
95 | 136 | { |
96 | - System.out.println("TCP: Error writing to socket"); | |
97 | 137 | break; |
98 | 138 | } |
139 | + else | |
140 | + { | |
141 | + System.out.println("FROM " + serv.getNickname(this) + ": " + str); | |
142 | + serv.sendToChat(this,str); | |
143 | + } | |
99 | 144 | } |
100 | - else | |
145 | + catch(IOException ioExc) | |
101 | 146 | { |
147 | + System.out.println("TCP: Error writing to socket"); | |
102 | 148 | break; |
103 | 149 | } |
104 | 150 | } |
... | ... | @@ -107,5 +153,4 @@ public class Connection extends Thread |
107 | 153 | serv.finishWorker(this); |
108 | 154 | } |
109 | 155 | } |
110 | - | |
111 | 156 | } | ... | ... |
JChatServer/src/pad/prac2/JChat.java
... | ... | @@ -25,7 +25,7 @@ public class JChat |
25 | 25 | { |
26 | 26 | public void run() |
27 | 27 | { |
28 | - System.out.println("JChat: interrupt catched, killing server..."); | |
28 | + System.out.println("JChat: Caught interrupt, killing server..."); | |
29 | 29 | serv.killServer(); |
30 | 30 | } |
31 | 31 | }); |
... | ... | @@ -34,8 +34,6 @@ public class JChat |
34 | 34 | /* |
35 | 35 | * TODO |
36 | 36 | * |
37 | - * unicast message | |
38 | - * list nicks | |
39 | - * disconnect/reconnect successfully | |
37 | + * CTRL+C | |
40 | 38 | */ |
41 | 39 | } | ... | ... |
JChatServer/src/pad/prac2/MyServerSocket.java
... | ... | @@ -12,22 +12,6 @@ public class MyServerSocket extends ServerSocket |
12 | 12 | super(); |
13 | 13 | } |
14 | 14 | |
15 | - public MySocket accept() | |
16 | - { | |
17 | - try | |
18 | - { | |
19 | - MySocket incoming = new MySocket(); | |
20 | - super.implAccept(incoming); | |
21 | - incoming.initializeStreams(); | |
22 | - return incoming; | |
23 | - } | |
24 | - catch(IOException ioExc) | |
25 | - { | |
26 | - System.out.println("TCP: Error accepting connection"); | |
27 | - return null; | |
28 | - } | |
29 | - } | |
30 | - | |
31 | 15 | public void bind(String ip, int port) |
32 | 16 | { |
33 | 17 | SocketAddress addr = new InetSocketAddress(ip,port); |
... | ... | @@ -41,6 +25,14 @@ public class MyServerSocket extends ServerSocket |
41 | 25 | } |
42 | 26 | } |
43 | 27 | |
28 | + public MySocket accept() throws IOException | |
29 | + { | |
30 | + MySocket incoming = new MySocket(); | |
31 | + super.implAccept(incoming); | |
32 | + incoming.initializeStreams(); | |
33 | + return incoming; | |
34 | + } | |
35 | + | |
44 | 36 | public void close() |
45 | 37 | { |
46 | 38 | try | ... | ... |
JChatServer/src/pad/prac2/MySocket.java
... | ... | @@ -45,28 +45,13 @@ public class MySocket extends Socket |
45 | 45 | } |
46 | 46 | } |
47 | 47 | |
48 | - public void close() | |
49 | - { | |
50 | - try | |
51 | - { | |
52 | - super.shutdownInput(); | |
53 | - super.shutdownOutput(); | |
54 | - super.close(); | |
55 | - } | |
56 | - catch(IOException ioExc) | |
57 | - { | |
58 | - System.out.println("TCP: Error while closing socket"); | |
59 | - } | |
60 | - } | |
61 | - | |
62 | 48 | public void sendMsg(String msg) throws IOException |
63 | 49 | { |
64 | 50 | String length = new Integer(msg.length()).toString(); |
65 | - this.write(length + '\0'); | |
66 | - this.write(msg); | |
51 | + this.write(length + '\0' + msg); | |
67 | 52 | } |
68 | 53 | |
69 | - public String recvMsg() | |
54 | + public String recvMsg() throws IOException | |
70 | 55 | { |
71 | 56 | String len,str; |
72 | 57 | int length; |
... | ... | @@ -100,28 +85,34 @@ public class MySocket extends Socket |
100 | 85 | } |
101 | 86 | } |
102 | 87 | |
103 | - public String readLine() | |
88 | + public String readLine() throws IOException | |
104 | 89 | { |
105 | - try | |
90 | + | |
91 | + String line = ""; | |
92 | + char[] c = new char[1]; | |
93 | + while(true) | |
106 | 94 | { |
107 | - String line = ""; | |
108 | - char[] c = new char[1]; | |
109 | - while(true) | |
95 | + input.read(c,0,1); | |
96 | + if(c[0] == '\0') | |
110 | 97 | { |
111 | - input.read(c,0,1); | |
112 | - if(c[0] == '\0') | |
113 | - { | |
114 | - break; | |
115 | - } | |
116 | - line += c[0]; | |
98 | + break; | |
117 | 99 | } |
118 | - return line; | |
100 | + line += c[0]; | |
101 | + } | |
102 | + return line; | |
103 | + } | |
104 | + | |
105 | + public void close() | |
106 | + { | |
107 | + try | |
108 | + { | |
109 | + super.shutdownInput(); | |
110 | + super.shutdownOutput(); | |
111 | + super.close(); | |
119 | 112 | } |
120 | 113 | catch(IOException ioExc) |
121 | 114 | { |
122 | - System.out.println("TCP: Error retrieving data from remote endpoint"); | |
123 | - return null; | |
115 | + System.out.println("TCP: Error while closing socket"); | |
124 | 116 | } |
125 | 117 | } |
126 | - | |
127 | 118 | } |
128 | 119 | \ No newline at end of file | ... | ... |
JChatServer/src/pad/prac2/Server.java
1 | 1 | package pad.prac2; |
2 | 2 | |
3 | 3 | import java.io.IOException; |
4 | +import java.util.Collection; | |
4 | 5 | import java.util.Iterator; |
5 | 6 | import java.util.Set; |
6 | 7 | import java.util.concurrent.ConcurrentHashMap; |
... | ... | @@ -44,35 +45,24 @@ public class Server |
44 | 45 | } |
45 | 46 | } |
46 | 47 | |
47 | - public void sendToChat(Connection origin, String message) throws IOException | |
48 | - { | |
49 | - lock.lock(); | |
50 | - String nickname = activeConnections.get(origin); | |
51 | - Set<Connection> connections = activeConnections.keySet(); | |
52 | - Iterator<Connection> it = connections.iterator(); | |
53 | - Connection conn; | |
54 | - while(it.hasNext()) | |
55 | - { | |
56 | - conn = it.next(); | |
57 | - if(conn != origin) | |
58 | - { | |
59 | - conn.sendMessage(nickname + ": " + message); | |
60 | - } | |
61 | - } | |
62 | - lock.unlock(); | |
63 | - } | |
64 | - | |
65 | 48 | public void startServer() |
66 | 49 | { |
67 | 50 | while(!kill) |
68 | 51 | { |
69 | - MySocket incoming = ss.accept(); | |
70 | - if(incoming != null) | |
52 | + try | |
71 | 53 | { |
54 | + MySocket incoming = ss.accept(); | |
72 | 55 | System.out.println("Accepted connection from " + incoming.getInetAddress()); |
73 | - | |
74 | 56 | startWorker(incoming); |
75 | 57 | } |
58 | + catch(IOException ioExc) | |
59 | + { | |
60 | + if(!kill) | |
61 | + { | |
62 | + System.out.println("TCP: Error accepting connection"); | |
63 | + break; | |
64 | + } | |
65 | + } | |
76 | 66 | } |
77 | 67 | |
78 | 68 | } |
... | ... | @@ -84,14 +74,20 @@ public class Server |
84 | 74 | { |
85 | 75 | try |
86 | 76 | { |
87 | - lock.unlock(); | |
88 | - availableWorkers.await(); | |
89 | - lock.lock(); | |
77 | + s.sendMsg("CHATFULL"); | |
78 | + synchronized(this) | |
79 | + { | |
80 | + availableWorkers.await(); | |
81 | + } | |
90 | 82 | } |
91 | 83 | catch(InterruptedException intExc) |
92 | 84 | { |
93 | 85 | intExc.printStackTrace(); |
94 | 86 | } |
87 | + catch(IOException ioExc) | |
88 | + { | |
89 | + System.out.println("TCP: Error while sending message to client"); | |
90 | + } | |
95 | 91 | } |
96 | 92 | workerPool[roomSize - freeWorkers].setSock(s); |
97 | 93 | workerPool[roomSize - freeWorkers].awake(); |
... | ... | @@ -100,34 +96,91 @@ public class Server |
100 | 96 | lock.unlock(); |
101 | 97 | } |
102 | 98 | |
103 | - public String getNickname(Connection c) | |
104 | - { | |
105 | - return activeConnections.get(c); | |
106 | - } | |
107 | - | |
108 | 99 | public void finishWorker(Connection c) |
109 | 100 | { |
110 | 101 | lock.lock(); |
102 | + removeFromChatroom(c); | |
111 | 103 | freeWorkers++; |
112 | 104 | workerPool[roomSize - freeWorkers] = c; |
113 | 105 | availableWorkers.signal(); |
114 | 106 | lock.unlock(); |
115 | 107 | } |
116 | 108 | |
109 | + public void sendTo(Connection orig, String nick, String msg) throws IOException, ChatException | |
110 | + { | |
111 | + lock.lock(); | |
112 | + System.out.println("FROM " + getNickname(orig) + " TO " + nick + ": " + msg); | |
113 | + msg = getNickname(orig) + ": " + msg; | |
114 | + Set<Connection> conns = activeConnections.keySet(); | |
115 | + Iterator<Connection> it = conns.iterator(); | |
116 | + Connection dest; | |
117 | + while(it.hasNext()) | |
118 | + { | |
119 | + dest = it.next(); | |
120 | + if(getNickname(dest).equals(nick)) | |
121 | + { | |
122 | + dest.sendMessage(msg); | |
123 | + lock.unlock(); | |
124 | + return; | |
125 | + } | |
126 | + } | |
127 | + lock.unlock(); | |
128 | + throw new ChatException("No such nickname"); | |
129 | + } | |
130 | + | |
131 | + public void sendToChat(Connection origin, String message) throws IOException | |
132 | + { | |
133 | + lock.lock(); | |
134 | + String nickname = activeConnections.get(origin); | |
135 | + Set<Connection> connections = activeConnections.keySet(); | |
136 | + Iterator<Connection> it = connections.iterator(); | |
137 | + Connection conn; | |
138 | + while(it.hasNext()) | |
139 | + { | |
140 | + conn = it.next(); | |
141 | + if(conn != origin) | |
142 | + { | |
143 | + conn.sendMessage(nickname + ": " + message); | |
144 | + } | |
145 | + } | |
146 | + lock.unlock(); | |
147 | + } | |
148 | + | |
149 | + public String getNickname(Connection c) | |
150 | + { | |
151 | + return activeConnections.get(c); | |
152 | + } | |
153 | + | |
117 | 154 | public void addToChatroom(Connection c, String nickName) |
118 | 155 | { |
119 | 156 | activeConnections.put(c, nickName); |
120 | 157 | System.out.println(nickName + " has entered the room"); |
121 | 158 | } |
122 | 159 | |
123 | - public void finishConnections() | |
160 | + private void removeFromChatroom(Connection c) | |
124 | 161 | { |
125 | - Set<Connection> conns = activeConnections.keySet(); | |
126 | - Iterator<Connection> it = conns.iterator(); | |
162 | + activeConnections.remove(c); | |
163 | + } | |
164 | + | |
165 | + public boolean isOnline(String nick) | |
166 | + { | |
167 | + return activeConnections.contains(nick); | |
168 | + } | |
169 | + | |
170 | + public String listOnline() | |
171 | + { | |
172 | + lock.lock(); | |
173 | + String ret = new Integer(activeConnections.size()).toString(); | |
174 | + ret += " people currently online:"; | |
175 | + Collection<String> nickNames = activeConnections.values(); | |
176 | + Iterator<String> it = nickNames.iterator(); | |
127 | 177 | while(it.hasNext()) |
128 | 178 | { |
129 | - it.next().finish(); | |
179 | + ret += "\n"; | |
180 | + ret += it.next(); | |
130 | 181 | } |
182 | + lock.unlock(); | |
183 | + return ret; | |
131 | 184 | } |
132 | 185 | |
133 | 186 | public void killServer() |
... | ... | @@ -136,4 +189,14 @@ public class Server |
136 | 189 | ss.close(); |
137 | 190 | finishConnections(); |
138 | 191 | } |
192 | + | |
193 | + public void finishConnections() | |
194 | + { | |
195 | + Set<Connection> conns = activeConnections.keySet(); | |
196 | + Iterator<Connection> it = conns.iterator(); | |
197 | + while(it.hasNext()) | |
198 | + { | |
199 | + it.next().finish(); | |
200 | + } | |
201 | + } | |
139 | 202 | } | ... | ... |