1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include "String.h"
#include "Socket.h"
#include "Exceptions.h"
#include "config.h"
#include "Input.h"
#include "Output.h"
Socket::Socket() throw (GeneralException) : Handle(socket(AF_INET, SOCK_STREAM, 0)), connected(false), listening(false) {
if (GetHandle() < 0) {
throw GeneralException("Error creating socket.");
}
}
Socket::Socket(int h) : Handle(h), connected(true), listening(false) { }
String Socket::GetName(void) {
return String("socket");
}
bool Socket::IsConnected(void) {
return connected;
}
bool Socket::IsListening(void) {
return listening;
}
bool Socket::CanRead(void) {
return connected;
}
bool Socket::CanWrite(void) {
return connected;
}
/***********************************************\
* Toute la suite n'est pas à décrire. Consulter *
* plutôt un document décrivant les sockets. *
\***********************************************/
bool Socket::SetLocal(String vhost, int port) {
struct hostent * localhostent;
struct in_addr localhostaddr;
struct sockaddr_in localsocketaddr;
memset((void *)&localhostaddr, 0, sizeof(localhostaddr));
if (vhost.strlen() != 0) {
if ((localhostent = gethostbyname(vhost.to_charp()))) {
memcpy((void *)&localhostaddr, localhostent->h_addr, sizeof(localhostaddr));
} else {
return false;
}
} else {
localhostaddr.s_addr = htonl(INADDR_ANY);
}
memset(&localsocketaddr, 0, sizeof(struct sockaddr_in));
localsocketaddr.sin_family = AF_INET;
localsocketaddr.sin_addr = localhostaddr;
localsocketaddr.sin_port = htons(port);
if (bind(GetHandle(), (struct sockaddr *) &localsocketaddr, sizeof(localsocketaddr)) < 0) {
return false;
} else {
return true;
}
}
bool Socket::Connect(String host, int port) {
struct hostent * remotehostent;
struct sockaddr_in remotesocketaddr;
if (!listening && !connected) {
cerr << " - Resolving '" << host << "'..." << endl;
if (!(remotehostent = gethostbyname(host.to_charp()))) {
return false;
}
remotesocketaddr.sin_family = AF_INET;
remotesocketaddr.sin_port = htons(port);
bcopy(remotehostent->h_addr, &remotesocketaddr.sin_addr, remotehostent->h_length);
cerr << " - Connecting to port " << port << " ..." << endl;
if (!connect(GetHandle(), (struct sockaddr *)&remotesocketaddr, sizeof(remotesocketaddr))) {
cerr << " - Connected." << endl;
connected = true;
} else {
cerr << " - Error connecting: " << strerror(errno) << endl;
}
}
return connected;
}
bool Socket::Listen(void) {
if (!listening && !connected) {
if (listen(GetHandle(), 10)) {
listening = true;
}
}
return listening;
}
Socket Socket::Accept(void) throw (GeneralException) {
struct sockaddr inaddr;
socklen_t inlen = sizeof(inaddr);
int h;
if ((h = accept(GetHandle(), &inaddr, &inlen)) < 0) {
throw GeneralException("Failed accepting.");
} else {
return Socket(h);
}
}
|