TConnection文件夹中文件:
TConnection.h:
#ifndef __TCP_CONNECTION_H__
#define __TCP_CONNECTION_H__
class TConnection
{
public:
static bool send(int sockfd, const char * data, int n);
static bool recv(int sockfd, char * buff, int n);
static bool setsndbuf(int sockfd, int size);
static bool setrcvbuf(int sockfd, int size);
static bool setrcvlow(int sockfd, int size);
protected:
int listen(const char * host, const char * serv);
int connect(const char * host, const char * serv);
int accept(int listenfd);
enum { LISTENQ = 1024, BUFFSIZ = 65536 };
};
#endif
TConnection.cpp:
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "TConnection.h"
bool TConnection::send(int sockfd, const char * data, int n)
{
ssize_t m;
while (n > 0) {
if ((m = write(sockfd, data, n)) <= 0) {
if (m < 0 && EINTR == errno) {
m = 0;
}
else {
printf("send error: %s\n", strerror(errno));
return(false);
}
}
n -= m;
data += m;
}
return(true);
}
bool TConnection::recv(int sockfd, char * buff, int n)
{
ssize_t m;
while (n > 0) {
if ((m = read(sockfd, buff, n)) <= 0) {
if (m < 0 && EINTR == errno) {
m = 0;
}
else {
printf("connection closed by peer\n", strerror(errno));
return(false);
}
}
n -= m;
buff += m;
}
return(true);
}
bool TConnection::setsndbuf(int sockfd, int size)
{
int bufsiz = 0;
socklen_t n = sizeof(int);
if (-1 == getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &bufsiz, &n)) {
printf("getsockopt error: %s\n", strerror(errno));
}
if (bufsiz >= size) {
return(true);
}
return(-1 != setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, n));
}
bool TConnection::setrcvbuf(int sockfd, int size)
{
int bufsiz = 0;
socklen_t n = sizeof(int);
if (-1 == getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &bufsiz, &n)) {
printf("getsockopt error: %s\n", strerror(errno));
}
if (bufsiz >= size) {
return(true);
}
return(-1 != setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, n));
}
bool TConnection::setrcvlow(int sockfd, int size)
{
if (-1 == setsockopt(sockfd, SOL_SOCKET, SO_RCVLOWAT,
&size, sizeof(socklen_t))) {
printf("setrcvlow error: %s\n", strerror(errno));
return(false);
}
return(true);
}
int TConnection::listen(const char * host, const char * serv)
{
int listenfd;
int n;
const int on = 1;
struct addrinfo hints;
struct addrinfo * res;
struct addrinfo * ressave;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (0 != (n = getaddrinfo(host, serv, &hints, &res))) {
printf("getaddrinfo error for %s, %s: %s\n",
(NULL == host) ? "(no hostname)" : host,
(NULL == serv) ? "(no servname)" : serv,
gai_strerror(n));
exit(1);
}
ressave = res;
while (NULL != res) {
listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (-1 != listenfd) {
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (0 == bind(listenfd, res->ai_addr, res->ai_addrlen)) {
break;
}
else {
close(listenfd);
}
}
res = res->ai_next;
}
freeaddrinfo(ressave);
if (NULL == res) {
printf("listen failed\n");
exit(1);
}
if (-1 == ::listen(listenfd, LISTENQ)) {
printf("listen error: %s\n", strerror(errno));
exit(1);
}
return(listenfd);
}
int TConnection::connect(const char * host, const char * serv)
{
int connfd;
int n;
struct addrinfo hints;
struct addrinfo * res;
struct addrinfo * ressave;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (0 != (n = getaddrinfo(host, serv, &hints, &res))) {
printf("getaddrinfo error for %s, %s: %s\n",
(NULL == host) ? "(no hostname)" : host,
(NULL == serv) ? "(no servname)" : serv,
gai_strerror(n));
exit(1);
}
ressave = res;
while (NULL != res) {
connfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (-1 != connfd) {
if (0 == ::connect(connfd, res->ai_addr, res->ai_addrlen)) {
break;
}
else {
close(connfd);
}
}
res = res->ai_next;
}
freeaddrinfo(ressave);
if (NULL == res) {
printf("connect failed\n");
exit(1);
}
return(connfd);
}
int TConnection::accept(int listenfd)
{
int accefd;
if (-1 == (accefd = ::accept(listenfd, NULL, NULL))) {
printf("accept error: %s\n", strerror(errno));
return(-1);
}
return(accefd);
}