C Liunx实现EchoServer非阻塞客户端(TPC协议)

介绍

C Liunx实现EchoServer非阻塞客户端(TPC协议)
服务端在:http://t.csdnimg.cn/5oJfI

支持库

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdbool.h>

代码

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdbool.h>

typedef struct EchoClientInfo
{
    int socketFD;
    struct sockaddr_in serverAddr;
    int bufferSize;
    struct timeval timeout;
    bool block;

} EchoClient;

EchoClient *InitClient();

int ConnectServer(EchoClient *client, char *ip, int port, bool noBlock);

int SendServerDate(EchoClient *client, char *date);

char *GetServerDate(EchoClient *client);

void CloseConnect(EchoClient *client);

void SetClientTimeout(EchoClient *client, int s, int us);

void FreeClient(EchoClient *client);

EchoClient *InitClient()
{
    EchoClient *result = (EchoClient *)malloc(sizeof(EchoClient));
    if (result != NULL)
    {
        memset(result, 0, sizeof(EchoClient));
        result->socketFD = 0;
        result->bufferSize = 1024;
        SetClientTimeout(result, 3, 0);
    }
    return result;

    return result;
}

int ConnectServer(EchoClient *client, char *ip, int port, bool noBlock)
{
    struct timeval timeout = client->timeout;
    int nRet,ret;

    client->socketFD = socket(AF_INET, SOCK_STREAM, 0);
    if (client->socketFD < 0)
        return -2;
    if (noBlock)
    {
        int flags = fcntl(client->socketFD, F_GETFL, 0);
        fcntl(client->socketFD, F_SETFL, flags | O_NONBLOCK);
    }
    client->block = !noBlock;

    client->serverAddr.sin_family = AF_INET;
    inet_pton(AF_INET, ip, &client->serverAddr.sin_addr);
    client->serverAddr.sin_port = htons(port);

    ret = connect(client->socketFD, (struct sockaddr *)&client->serverAddr, sizeof(client->serverAddr));

    if (client->block && ret == 0)
        goto Success;

    fd_set wait;
    FD_ZERO(&wait);
    FD_SET(client->socketFD, &wait);

    nRet = select(client->socketFD + 1, NULL, &wait, NULL, &timeout);

    if (nRet == 0)
        return -1;
    else if (nRet < 0)
        return -2;

Success:
    return 0;
}

char *GetServerDate(EchoClient *client)
{
    int len, ready, size = 1;
    char *temp;
    char *result = (char *)malloc(sizeof(char));
    char *buffer = (char *)malloc(sizeof(char) * client->bufferSize);
    if (!result)
        return "";
    else
        result[0] = '\0';

    if (!buffer)
        return "";
    else
        buffer[0] = '\0';

    struct timeval timeout = client->timeout;
    fd_set wait;
    FD_ZERO(&wait);
    FD_SET(client->socketFD, &wait);

    while (true)
    {
        if (client->block)
            goto ReadMessage;
        ready = select(client->socketFD + 1, &wait, NULL, NULL, &timeout);
        if (ready > 0)
        {
            if (FD_ISSET(client->socketFD, &wait))
            {
            ReadMessage:
                len = read(client->socketFD, buffer, client->bufferSize - 1);
                if (len > 0)
                {
                    size += len;
                    buffer[len] = '\0';
                    temp = (char *)realloc(result, sizeof(char) * size);
                    if (!temp)
                        break;
                    strcpy(temp, result);
                    result = temp;
                    strcat(result, buffer);
                    if (client->block)
                        continue;
                }
                else
                    break;
            }
        }
        else
            break;
    }
    return result;
}

int SendServerDate(EchoClient *client, char *date)
{
    return write(client->socketFD, date, strlen(date));
}

void CloseConnect(EchoClient *client)
{
    if (client->socketFD)
        close(client->socketFD);
}

void SetClientTimeout(EchoClient *client, int s, int us)
{
    client->timeout.tv_sec = s;
    client->timeout.tv_usec = us;
}

void FreeClient(EchoClient *client){
    free(client);
}

示例

假设服务端地址:192.168.2.2 | 端口是1001

#include <stdio.h>

int main()
{
    EchoClient *client = InitClient();
    SetClientTimeout(client,10,0);
    char *message, ret, con;
    while (true)
    {
        printf("尝试连接");
        con = ConnectServer(client, "192.168.2.2", 1001, true);
        if (con == 0)
        {
            ret = SendServerDate(client, "hello");
            if (ret > 0)
            {
                message = GetServerDate(client);
                printf("-->来自服务端的消息:%s", message);
            }
        }
        CloseConnect(client);
        printf("\n");
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

STHUDY

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值