|
1
2
3
4
5
6
7
|
/** @file
* \brief Fichero de implementación de un cliente
* \author Imanol Barba Sabariego
* \date 13/06/2013
*
* En este fichero se implementa un cliente para poder usar con el servidor creado, usando la clase Socket.
*/
|
|
8
|
#include "client.h"
|
|
9
10
11
12
13
14
15
16
17
18
|
using namespace std;
bool connected, finished;
//! Método para terminar el cliente
/*! Este método se usa para terminar el cliente immediatamente en el caso que el servidor cierre la conexión de forma inesperada, capturando
el signal SIGPIPE. */
void exitClient(int signal/*!<Parámetro que captura el signal recibido*/)
{
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
if(signal == SIGPIPE)
{
cout << "Server connection terminated unexpectedly" << endl << "Exiting" << endl;
exit(-1);
}
}
void killThread(thread_args *t_arg)
{
(t_arg->s)->Close();
pthread_mutex_lock(t_arg->mutex);
if(t_arg->s != 0)
{
delete t_arg->s;
t_arg->s = 0;
}
if(t_arg != 0)
{
delete t_arg;
t_arg = 0;
}
pthread_exit(NULL);
|
|
41
42
43
44
|
}
bool connect(Socket& s)
{
|
|
45
|
string host, nick;
|
|
46
|
int port;
|
|
47
|
/*cout << "Hostname: ";
|
|
48
49
|
cin >> host;
cout << "Port: ";
|
|
50
51
52
|
cin >> port;*/
cout << "Nickname: ";
cin >> nick;
|
|
53
|
cin.ignore();
|
|
54
55
56
|
host = "localhost";
port = 3001;
|
|
57
58
59
60
61
|
try
{
s.Connect(host,port);
cout << "Connected" << endl;
connected = true;
|
|
62
|
s << nick;
|
|
63
64
65
66
67
68
69
|
}
catch(SocketException& e)
{
cout << e.description() << endl;
}
}
|
|
70
|
void* sendThread(void* args)
|
|
71
|
{
|
|
72
73
74
|
string send;
struct thread_args *t_arg = (struct thread_args*)args;
while(true)
|
|
75
|
{
|
|
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
cout << "> ";
getline(cin,send);
if(cin.eof())
{
send = "/disconnect";
}
try
{
*(t_arg->s) << send;
if(send == "/disconnect" || send == "/exit")
{
break;
}
}
catch(SocketException& e)
{
cout << e.description() << endl;
cout << "Exiting" << endl;
(t_arg->s)->Close();
exit(-1);
}
|
|
97
|
}
|
|
98
99
100
101
102
103
104
105
|
killThread(t_arg);
}
void* recvThread(void* args)
{
string recv;
struct thread_args *t_arg = (struct thread_args*)args;
while(true)
|
|
106
|
{
|
|
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
*(t_arg->s) >> recv;
if(recv == "DISC_OK")
{
cout << "Disconnecting" << endl;
(t_arg->s)->Close();
connected = false;
pthread_cond_signal(t_arg->condition);
break;
}
else if(recv == "EXIT_OK")
{
cout << "Exiting" << endl;
(t_arg->s)->Close();
connected = false;
finished = true;
pthread_cond_signal(t_arg->condition);
break;
}
else
{
cout << recv << endl;
}
|
|
129
|
}
|
|
130
|
killThread(t_arg);
|
|
131
132
133
134
135
136
137
138
139
|
}
//! Método principal del cliente
/*! Este método inicializa el Socket, establece la conexión y realiza las acciones que se le hayan programado para comunicarse con el servidor.*/
int main()
{
signal(SIGPIPE, exitClient);
Socket s;
connected = finished = false;
|
|
140
141
142
143
144
145
146
|
pthread_mutex_t mutex;
pthread_mutex_init(&mutex,0);
pthread_cond_t condition;
pthread_cond_init(&condition,0);
thread_args *sArgs = new thread_args;
thread_args *rArgs = new thread_args;
pthread_t recv, send;
|
|
147
|
s.Create();
|
|
148
|
while (!finished)
|
|
149
150
|
{
connect(s);
|
|
151
152
153
154
155
156
157
158
159
160
161
162
|
pthread_mutex_lock(&mutex);
sArgs->mutex = &mutex;
sArgs->condition = &condition;
sArgs->s = &s;
rArgs->mutex = &mutex;
rArgs->condition = &condition;
rArgs->s = &s;
pthread_create(&send,NULL,sendThread,(void *)sArgs);
pthread_create(&recv,NULL,recvThread,(void *)rArgs);
|
|
163
164
|
while(connected)
{
|
|
165
|
pthread_cond_wait(&condition,&mutex);
|
|
166
|
}
|
|
167
|
pthread_mutex_unlock(&mutex);
|
|
168
|
}
|
|
169
170
|
pthread_cond_destroy(&condition);
pthread_mutex_destroy(&mutex);
|
|
171
172
|
}
|
|
173
|
/* TODO
|
|
174
|
*
|
|
175
|
* disconnecting causes some real shit
|
|
176
177
178
|
* list nicks
* unicast message
*/
|