TCP 简易代码

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>

typedef struct 
{
    int             sockfd;
    int             connfd;
    unsigned short  tcpPort;
} FAX_INFO_T;


int recv_message(int sockfd, char *buf, int len)
{
    int count = 0, ret;

    for (; ;)
    {
        ret = recv(sockfd, buf + count, len - count, 0);
        if (ret <= 0)      /*出错时,返回<0 即close(sockfd),以后在调用recv会出错*/
        {
            perror ("recv failed.");
            return -1;
        }

        count += ret; 
        if (count == len)
        {
            break;
        }
    }

    return 0;
}
int send_message(int sockfd, char *buf, int len)
{
    int count = 0, ret;

    for (; ;)
    {
        ret = send(sockfd, buf + count, len - count, 0);
        if (ret <= 0)
        {
            perror("send failed");
            return -1;
        }

        count += ret; 
        if (count == len)
        {
            break;
        }
    }

    return 0;
}

1、初始化TCP套接字

int initFaxTcpSocket()
{
    int sockfd;
    int iRet, on;

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("[%s %d] socket failed.\r\n", __FILE__, __LINE__);
        return -1;
    }

    /* 服务端需设置此项 */
    on = 1;
    iRet = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
    if (iRet < 0)
    {
        close(sockfd);
        printf("[%s %d] setsockopt failed", __FILE__, __LINE__);
        return -1;
    }
    
    return sockfd;
}

2、服务端处理:等待客户连接处理

int waitClientConnect(FAX_INFO_T *info)
{
    int connfd;
    int iRet, connFlag = 1;
    fd_set fdset;
    struct timeval tv;

    struct sockaddr_in cliAddr, serAddr;
    int iAddrLen = sizeof(struct sockaddr_in);

    serAddr.sin_family = AF_INET;
    serAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serAddr.sin_port = htons(info->tcpPort);

    /* bind */
    iRet = bind(info->sockfd, (struct sockaddr *)&serAddr, iAddrLen);
    if (iRet != 0)
    {
        printf("[%s %d][TCP SVR] bind failed.\r\n", __FILE__, __LINE__);
        return -1;
    }
    /* listen */
    if (listen(info->sockfd, 1) != 0)       /*只允许同时1个客户端连接,即在此端口上只能连接一路传真发送方*/
    {
        printf("[%s %d] listen failed.\r\n", __FILE__, __LINE__);
        return -1;
    }

    /* vxworks 不知道是否有errno错误值 errno == EINTR*/
    /* accept,加select超时,防止客户端在accept之前失去连接,导致该任务一直阻塞于accept*/
    FD_ZERO(&fdset);
    FD_SET(info->sockfd, &fdset);
    
    tv.tv_sec = 9;
    tv.tv_usec = 0;
        
    iRet = select(info->sockfd + 1, &fdset, NULL, NULL, &tv);
    if (iRet > 0)
    {
        /*成功则为非负描述符*/
        connfd = accept(info->sockfd, (struct sockaddr *)&cliAddr, &iAddrLen);
        if (connfd < 0)
        {
            printf("[%s %d] accept failed. \r\n", __FILE__, __LINE__);
            return -1;
        }
        else
        {
            info->connfd = connfd;
            printf("[%s %d] accept succ. connfd = %d\r\n", __FILE__, __LINE__, connfd);
            return 0;
        }
    }
    else      /* == 0 timeout  || < 0 error*/
    {
        printf("[%s %d] select timeout or Failed\r\n", __FILE__, __LINE__);
        return -1;
    }
}

3、客户端处理:执行connect

猜你喜欢

转载自blog.csdn.net/centnetHY/article/details/89178182
tcp