Newer
Older
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include "screen.hh"
#include "error.hh"
Connection::Connection() : socket_(0) {}
// make connection
connect_(O.server.c_str(), O.port);
// send login info
// send pass info
// Start reader thread
pthread_create(&g_thread_reader, 0, thread_reader, 0);
void Connection::connect_(const char *addr, int port) {
struct sockaddr_in daddr;
struct hostent *h;
// Check no existing connexion
assert(socket_ == 0);
// retrieve remote host info
h = gethostbyname(addr);
if (h == 0) {
S << "Unable to resolve: " << addr << ": " << hstrerror(h_errno) << ".\n";
return;
}
socket_ = socket(PF_INET, SOCK_STREAM, 0);
if (socket_ == -1) {
S << "Unable to create socket: " << strerror(errno) << ".\n";
socket_ = 0;
daddr.sin_family = AF_INET;
daddr.sin_port = htons(port);
daddr.sin_addr = *((struct in_addr *) h->h_addr);
memset(daddr.sin_zero, '\0', sizeof daddr.sin_zero);
S << "Connecting to " << h->h_name << " (" << inet_ntoa(*(struct in_addr*)h->h_addr)
<< ") on port " << port << "...\n";
// connect
pthread_mutex_lock(&mtx_socket);
int con = connect(socket_, (struct sockaddr *) &daddr, sizeof daddr);
pthread_mutex_unlock(&mtx_socket);
if (con == -1) {
disconnect_();
S << "Unable to connect: " << strerror(errno);
return;
}
S << "Connected to " << h->h_name << " (" << inet_ntoa(*(struct in_addr*)h->h_addr)
<< ") on port " << port << "...\n";
}
void Connection::disconnect_() {
void Connection::send(const string &data) {
send(data.c_str(), data.length());
}
void Connection::send(const char* buf, size_t len) {
}
void Connection::sendln(const string &data) {
sendln(data.c_str(), data.length());
}
void Connection::sendln(const char* buf, size_t len) {
assert(socket_ > 0);
pthread_mutex_lock(&mtx_socket);
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
do {
// check EOL char
size_t offset = rbuf_.find('\n');
if (offset != string::npos) {
string s = rbuf_.substr(0, offset);
rbuf_.erase(0, offset + 1);
return s;
}
// wait incoming data
static struct pollfd spfd[1] = {{socket_, POLLIN|POLLPRI|POLLHUP|POLLERR, 0}};
poll(spfd, 1, -1);
// lock before read
pthread_mutex_lock(&mtx_socket);
// read data
static char local_buf[MAX_LINE_SIZE];
int ret = ::recv(socket_, local_buf, MAX_LINE_SIZE, MSG_DONTWAIT);
// unlock
pthread_mutex_unlock(&mtx_socket);
if (ret == -1) {
disconnect_();
*local_buf = 0;
}
else local_buf[ret] = 0;
// add read data in buffer
rbuf_ += local_buf;
} while (1);
assert(1);