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,11 +6,6 @@ | ||
6 | * En este fichero se implementan los métodos de la clase Socket definidos en Socket.h | 6 | * En este fichero se implementan los métodos de la clase Socket definidos en Socket.h |
7 | */ | 7 | */ |
8 | #include "Socket.h" | 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 | using namespace std; | 10 | using namespace std; |
16 | 11 | ||
@@ -149,8 +144,11 @@ const Socket& Socket::operator << ( const std::string& text) | @@ -149,8 +144,11 @@ const Socket& Socket::operator << ( const std::string& text) | ||
149 | } | 144 | } |
150 | sstream << length; | 145 | sstream << length; |
151 | string len = sstream.str(); | 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 | return *this; | 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,13 +25,6 @@ void exitClient(int signal/*!<Parámetro que captura el signal recibido*/) | ||
25 | 25 | ||
26 | void killThread(thread_args *t_arg) | 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 | if(t_arg != 0) | 28 | if(t_arg != 0) |
36 | { | 29 | { |
37 | delete t_arg; | 30 | delete t_arg; |
@@ -42,42 +35,69 @@ void killThread(thread_args *t_arg) | @@ -42,42 +35,69 @@ void killThread(thread_args *t_arg) | ||
42 | 35 | ||
43 | bool connect(Socket& s) | 36 | bool connect(Socket& s) |
44 | { | 37 | { |
45 | - string host, nick; | 38 | + string host, nick, response; |
46 | int port; | 39 | int port; |
47 | /*cout << "Hostname: "; | 40 | /*cout << "Hostname: "; |
48 | - cin >> host; | 41 | + getline(cin,host); |
49 | cout << "Port: "; | 42 | cout << "Port: "; |
50 | cin >> port;*/ | 43 | cin >> port;*/ |
51 | cout << "Nickname: "; | 44 | cout << "Nickname: "; |
52 | - cin >> nick; | ||
53 | - cin.ignore(); | 45 | + getline(cin,nick); |
54 | host = "localhost"; | 46 | host = "localhost"; |
55 | port = 3001; | 47 | port = 3001; |
56 | 48 | ||
57 | try | 49 | try |
58 | { | 50 | { |
51 | + s.Create(); | ||
59 | s.Connect(host,port); | 52 | s.Connect(host,port); |
60 | cout << "Connected" << endl; | 53 | cout << "Connected" << endl; |
61 | connected = true; | 54 | connected = true; |
62 | s << nick; | 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 | catch(SocketException& e) | 82 | catch(SocketException& e) |
65 | { | 83 | { |
66 | cout << e.description() << endl; | 84 | cout << e.description() << endl; |
85 | + exit(-1); | ||
67 | } | 86 | } |
87 | + return true; | ||
68 | } | 88 | } |
69 | 89 | ||
70 | void* sendThread(void* args) | 90 | void* sendThread(void* args) |
71 | { | 91 | { |
72 | string send; | 92 | string send; |
73 | struct thread_args *t_arg = (struct thread_args*)args; | 93 | struct thread_args *t_arg = (struct thread_args*)args; |
74 | - while(true) | 94 | + while(connected) |
75 | { | 95 | { |
76 | cout << "> "; | 96 | cout << "> "; |
77 | getline(cin,send); | 97 | getline(cin,send); |
78 | if(cin.eof()) | 98 | if(cin.eof()) |
79 | { | 99 | { |
80 | - send = "/disconnect"; | 100 | + send = "/exit"; |
81 | } | 101 | } |
82 | try | 102 | try |
83 | { | 103 | { |
@@ -90,9 +110,6 @@ void* sendThread(void* args) | @@ -90,9 +110,6 @@ void* sendThread(void* args) | ||
90 | catch(SocketException& e) | 110 | catch(SocketException& e) |
91 | { | 111 | { |
92 | cout << e.description() << endl; | 112 | cout << e.description() << endl; |
93 | - cout << "Exiting" << endl; | ||
94 | - (t_arg->s)->Close(); | ||
95 | - exit(-1); | ||
96 | } | 113 | } |
97 | } | 114 | } |
98 | killThread(t_arg); | 115 | killThread(t_arg); |
@@ -104,11 +121,20 @@ void* recvThread(void* args) | @@ -104,11 +121,20 @@ void* recvThread(void* args) | ||
104 | struct thread_args *t_arg = (struct thread_args*)args; | 121 | struct thread_args *t_arg = (struct thread_args*)args; |
105 | while(true) | 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 | if(recv == "DISC_OK") | 135 | if(recv == "DISC_OK") |
109 | { | 136 | { |
110 | cout << "Disconnecting" << endl; | 137 | cout << "Disconnecting" << endl; |
111 | - (t_arg->s)->Close(); | ||
112 | connected = false; | 138 | connected = false; |
113 | pthread_cond_signal(t_arg->condition); | 139 | pthread_cond_signal(t_arg->condition); |
114 | break; | 140 | break; |
@@ -116,7 +142,6 @@ void* recvThread(void* args) | @@ -116,7 +142,6 @@ void* recvThread(void* args) | ||
116 | else if(recv == "EXIT_OK") | 142 | else if(recv == "EXIT_OK") |
117 | { | 143 | { |
118 | cout << "Exiting" << endl; | 144 | cout << "Exiting" << endl; |
119 | - (t_arg->s)->Close(); | ||
120 | connected = false; | 145 | connected = false; |
121 | finished = true; | 146 | finished = true; |
122 | pthread_cond_signal(t_arg->condition); | 147 | pthread_cond_signal(t_arg->condition); |
@@ -144,10 +169,15 @@ int main() | @@ -144,10 +169,15 @@ int main() | ||
144 | thread_args *sArgs = new thread_args; | 169 | thread_args *sArgs = new thread_args; |
145 | thread_args *rArgs = new thread_args; | 170 | thread_args *rArgs = new thread_args; |
146 | pthread_t recv, send; | 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 | while (!finished) | 175 | while (!finished) |
149 | { | 176 | { |
150 | - connect(s); | 177 | + if(!connect(s)) |
178 | + { | ||
179 | + exit(-1); | ||
180 | + } | ||
151 | pthread_mutex_lock(&mutex); | 181 | pthread_mutex_lock(&mutex); |
152 | sArgs->mutex = &mutex; | 182 | sArgs->mutex = &mutex; |
153 | sArgs->condition = &condition; | 183 | sArgs->condition = &condition; |
@@ -157,14 +187,17 @@ int main() | @@ -157,14 +187,17 @@ int main() | ||
157 | rArgs->condition = &condition; | 187 | rArgs->condition = &condition; |
158 | rArgs->s = &s; | 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 | while(connected) | 193 | while(connected) |
164 | { | 194 | { |
165 | pthread_cond_wait(&condition,&mutex); | 195 | pthread_cond_wait(&condition,&mutex); |
166 | } | 196 | } |
167 | pthread_mutex_unlock(&mutex); | 197 | pthread_mutex_unlock(&mutex); |
198 | + pthread_join(recv,NULL); | ||
199 | + pthread_join(send,NULL); | ||
200 | + s.Close(); | ||
168 | } | 201 | } |
169 | pthread_cond_destroy(&condition); | 202 | pthread_cond_destroy(&condition); |
170 | pthread_mutex_destroy(&mutex); | 203 | pthread_mutex_destroy(&mutex); |
@@ -172,7 +205,5 @@ int main() | @@ -172,7 +205,5 @@ int main() | ||
172 | 205 | ||
173 | /* TODO | 206 | /* TODO |
174 | * | 207 | * |
175 | - * disconnecting causes some real shit | ||
176 | - * list nicks | ||
177 | - * unicast message | 208 | + * CTRL+C |
178 | */ | 209 | */ |
179 | \ No newline at end of file | 210 | \ No newline at end of file |
JChatClient/src/include/Socket.h
@@ -9,13 +9,17 @@ | @@ -9,13 +9,17 @@ | ||
9 | #define SOCKET_H_ | 9 | #define SOCKET_H_ |
10 | 10 | ||
11 | #include <iostream> | 11 | #include <iostream> |
12 | +#include <sstream> | ||
13 | +#include "SocketException.h" | ||
12 | #include <sys/socket.h> | 14 | #include <sys/socket.h> |
15 | +#include <sys/types.h> | ||
13 | #include <netinet/in.h> | 16 | #include <netinet/in.h> |
17 | +#include <netinet/tcp.h> | ||
14 | #include <arpa/inet.h> | 18 | #include <arpa/inet.h> |
15 | #include <netdb.h> | 19 | #include <netdb.h> |
16 | -#include <string> | ||
17 | -#include <sys/types.h> | ||
18 | #include <unistd.h> | 20 | #include <unistd.h> |
21 | +#include <cstdlib> | ||
22 | +#include <cstring> | ||
19 | 23 | ||
20 | using namespace std; | 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,11 +15,6 @@ public class Connection extends Thread | ||
15 | sleep = true; | 15 | sleep = true; |
16 | } | 16 | } |
17 | 17 | ||
18 | - public void sendMessage(String message) throws IOException | ||
19 | - { | ||
20 | - socket.sendMsg(message); | ||
21 | - } | ||
22 | - | ||
23 | public void awake() | 18 | public void awake() |
24 | { | 19 | { |
25 | synchronized(this) | 20 | synchronized(this) |
@@ -32,9 +27,12 @@ public class Connection extends Thread | @@ -32,9 +27,12 @@ public class Connection extends Thread | ||
32 | public void finish() | 27 | public void finish() |
33 | { | 28 | { |
34 | kill = true; | 29 | kill = true; |
35 | - sleep = false; | 30 | + if(sleep) |
31 | + { | ||
32 | + sleep = false; | ||
33 | + notify(); | ||
34 | + } | ||
36 | socket.close(); | 35 | socket.close(); |
37 | - this.notify(); | ||
38 | } | 36 | } |
39 | 37 | ||
40 | public void setSock(MySocket s) | 38 | public void setSock(MySocket s) |
@@ -42,6 +40,11 @@ public class Connection extends Thread | @@ -42,6 +40,11 @@ public class Connection extends Thread | ||
42 | socket = s; | 40 | socket = s; |
43 | } | 41 | } |
44 | 42 | ||
43 | + public void sendMessage(String message) throws IOException | ||
44 | + { | ||
45 | + socket.sendMsg(message); | ||
46 | + } | ||
47 | + | ||
45 | public void run() | 48 | public void run() |
46 | { | 49 | { |
47 | while(!kill) | 50 | while(!kill) |
@@ -60,45 +63,88 @@ public class Connection extends Thread | @@ -60,45 +63,88 @@ public class Connection extends Thread | ||
60 | e.printStackTrace(); | 63 | e.printStackTrace(); |
61 | } | 64 | } |
62 | } | 65 | } |
63 | - String str = socket.recvMsg(); | ||
64 | - serv.addToChatroom(this, str); | ||
65 | if(!kill) | 66 | if(!kill) |
66 | { | 67 | { |
67 | - while(true) | 68 | + String str; |
69 | + try | ||
68 | { | 70 | { |
69 | str = socket.recvMsg(); | 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 | break; | 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 | break; | 148 | break; |
103 | } | 149 | } |
104 | } | 150 | } |
@@ -107,5 +153,4 @@ public class Connection extends Thread | @@ -107,5 +153,4 @@ public class Connection extends Thread | ||
107 | serv.finishWorker(this); | 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,7 +25,7 @@ public class JChat | ||
25 | { | 25 | { |
26 | public void run() | 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 | serv.killServer(); | 29 | serv.killServer(); |
30 | } | 30 | } |
31 | }); | 31 | }); |
@@ -34,8 +34,6 @@ public class JChat | @@ -34,8 +34,6 @@ public class JChat | ||
34 | /* | 34 | /* |
35 | * TODO | 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,22 +12,6 @@ public class MyServerSocket extends ServerSocket | ||
12 | super(); | 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 | public void bind(String ip, int port) | 15 | public void bind(String ip, int port) |
32 | { | 16 | { |
33 | SocketAddress addr = new InetSocketAddress(ip,port); | 17 | SocketAddress addr = new InetSocketAddress(ip,port); |
@@ -41,6 +25,14 @@ public class MyServerSocket extends ServerSocket | @@ -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 | public void close() | 36 | public void close() |
45 | { | 37 | { |
46 | try | 38 | try |
JChatServer/src/pad/prac2/MySocket.java
@@ -45,28 +45,13 @@ public class MySocket extends Socket | @@ -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 | public void sendMsg(String msg) throws IOException | 48 | public void sendMsg(String msg) throws IOException |
63 | { | 49 | { |
64 | String length = new Integer(msg.length()).toString(); | 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 | String len,str; | 56 | String len,str; |
72 | int length; | 57 | int length; |
@@ -100,28 +85,34 @@ public class MySocket extends Socket | @@ -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 | catch(IOException ioExc) | 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 | \ No newline at end of file | 119 | \ No newline at end of file |
JChatServer/src/pad/prac2/Server.java
1 | package pad.prac2; | 1 | package pad.prac2; |
2 | 2 | ||
3 | import java.io.IOException; | 3 | import java.io.IOException; |
4 | +import java.util.Collection; | ||
4 | import java.util.Iterator; | 5 | import java.util.Iterator; |
5 | import java.util.Set; | 6 | import java.util.Set; |
6 | import java.util.concurrent.ConcurrentHashMap; | 7 | import java.util.concurrent.ConcurrentHashMap; |
@@ -44,35 +45,24 @@ public class Server | @@ -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 | public void startServer() | 48 | public void startServer() |
66 | { | 49 | { |
67 | while(!kill) | 50 | while(!kill) |
68 | { | 51 | { |
69 | - MySocket incoming = ss.accept(); | ||
70 | - if(incoming != null) | 52 | + try |
71 | { | 53 | { |
54 | + MySocket incoming = ss.accept(); | ||
72 | System.out.println("Accepted connection from " + incoming.getInetAddress()); | 55 | System.out.println("Accepted connection from " + incoming.getInetAddress()); |
73 | - | ||
74 | startWorker(incoming); | 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,14 +74,20 @@ public class Server | ||
84 | { | 74 | { |
85 | try | 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 | catch(InterruptedException intExc) | 83 | catch(InterruptedException intExc) |
92 | { | 84 | { |
93 | intExc.printStackTrace(); | 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 | workerPool[roomSize - freeWorkers].setSock(s); | 92 | workerPool[roomSize - freeWorkers].setSock(s); |
97 | workerPool[roomSize - freeWorkers].awake(); | 93 | workerPool[roomSize - freeWorkers].awake(); |
@@ -100,34 +96,91 @@ public class Server | @@ -100,34 +96,91 @@ public class Server | ||
100 | lock.unlock(); | 96 | lock.unlock(); |
101 | } | 97 | } |
102 | 98 | ||
103 | - public String getNickname(Connection c) | ||
104 | - { | ||
105 | - return activeConnections.get(c); | ||
106 | - } | ||
107 | - | ||
108 | public void finishWorker(Connection c) | 99 | public void finishWorker(Connection c) |
109 | { | 100 | { |
110 | lock.lock(); | 101 | lock.lock(); |
102 | + removeFromChatroom(c); | ||
111 | freeWorkers++; | 103 | freeWorkers++; |
112 | workerPool[roomSize - freeWorkers] = c; | 104 | workerPool[roomSize - freeWorkers] = c; |
113 | availableWorkers.signal(); | 105 | availableWorkers.signal(); |
114 | lock.unlock(); | 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 | public void addToChatroom(Connection c, String nickName) | 154 | public void addToChatroom(Connection c, String nickName) |
118 | { | 155 | { |
119 | activeConnections.put(c, nickName); | 156 | activeConnections.put(c, nickName); |
120 | System.out.println(nickName + " has entered the room"); | 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 | while(it.hasNext()) | 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 | public void killServer() | 186 | public void killServer() |
@@ -136,4 +189,14 @@ public class Server | @@ -136,4 +189,14 @@ public class Server | ||
136 | ss.close(); | 189 | ss.close(); |
137 | finishConnections(); | 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 | } |