一个简单的文件共享工程 -- TConnection

49 篇文章 0 订阅
20 篇文章 0 订阅

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);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值