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

本文介绍了如何使用C语言在Linux下实现一个非阻塞的EchoServer客户端,包括初始化客户端、连接服务器、发送数据以及接收服务器响应。示例代码展示了客户端的完整流程。

介绍

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

<think>好的,我需要帮助用户解决在Linux环境下配置服务器A和客户端C连接到VN1交换机的问题。首先,我需要明确用户的需求。VN1可能指的是VLAN ID为1的虚拟局域网,或者是某种特定名称的交换机配置。不过,通常VLAN ID1是默认的本地VLAN,可能用户是想将服务器客户端配置到同一个VLAN中,或者特定的VLAN里。需要进一步确认,但根据常见情况,假设VN1是VLANID1。接下来,我需要回忆Linux中配置网络接口和VLAN的方法。根据引用[2],Linux可以使用vconfig命令来添加VLAN设备。另外,现在可能更常用的是ip命令中的vlan子命令。例如,使用ip linkadd linketh0 nameeth0.1type vlan id1来创建VLAN接口。用户提到服务器A和客户端C连接到VN1交换机。这可能意味着需要在服务器客户端上配置对应的VLAN接口,并设置正确的IP地址,确保它们在同一个VLAN下可以通信。步骤可能包括: 1.在服务器A和客户端C上安装必要的VLAN支持工具(如vlan软件包)。2.创建VLAN接口,分配VLAN ID。 3.配置IP地址到VLAN接口。4.确保交换机端口配置正确,允许对应的VLAN通过(比如设置为access模式或trunk模式,具体取决于网络拓扑)。 需要检查是否安装了vlan软件包,如果没有,需要安装。然后使用vconfig或ip命令创建VLAN接口。例如,在服务器A上,如果物理接口是eth0,创建VLAN1接口:sudo iplink addlink eth0 nameeth0.1type vlan id1然后分配IP地址: sudoip addradd192.168.1.2/24 deveth0.1sudoip linkset eth0.1 up客户端C同理,配置不同的IP地址,如192.168.1.3/24。此外,交换机的配置也需要正确设置端口为VLAN1的成员,可能需要设置端口的PVID为1,根据引用[2]中的内容,可能需要使用vconfig命令设置PVID。不过通常交换机的配置需要登录交换机进行设置,比如在支持VLAN的交换机上,将连接服务器A和客户端C的端口设置为VLAN1的access端口。另外,用户提到的VN1可能不是VLAN1,而是自定义的VLAN名称,这时候需要确认具体的VLANID,比如VN1对应的是VLAN100或者其他ID,步骤类似,只需替换对应的VLANID即可。 需要提醒用户,如果交换机未正确配置对应的VLAN,Linux主机的VLAN配置可能无法通信。因此,确保交换机端也进行了相应的VLAN设置,比如创建VLAN并分配端口。总结步骤: 1.安装必要的软件包(vlan)。2.创建VLAN接口。3.分配IP地址并启用接口。4.配置交换机端口对应的VLAN。5.测试连通性。可能遇到的问题包括:VLAN接口未正确创建,IP地址冲突,交换机配置错误,防火墙设置阻止通信等。需要检查这些方面。根据引用[3],如果使用iptables,可能需要配置防火墙规则允许VLAN通信,或者暂时关闭防火墙进行测试。最后,生成相关问题,帮助用户深入理解。</think>在Linux环境下配置服务器A和客户端C连接到支持VLAN的交换机(假设VN1为VLAN ID 1),需完成以下步骤: --- ### **配置步骤** 1. **安装VLAN支持工具** 确保系统已安装`vlan`软件包: ```bash sudo apt install vlan # Debian/Ubuntu sudo yum install vlan # RHEL/CentOS ``` 2. **创建VLAN接口** - **服务器A**(假设物理网卡为`eth0`,VLAN ID=1): ```bash sudo ip link add link eth0 name eth0.1 type vlan id 1 sudo ip addr add 192.168.1.2/24 dev eth0.1 sudo ip link set eth0.1 up ``` - **客户端C**(配置相同VLAN,不同IP): ```bash sudo ip link add link eth0 name eth0.1 type vlan id 1 sudo ip addr add 192.168.1.3/24 dev eth0.1 sudo ip link set eth0.1 up ``` 3. **交换机配置(关键步骤)** - 登录交换机管理界面,将连接服务器A和客户端C的端口配置为**Access模式**,并设置**PVID=1**(即VN1的VLAN ID)。 - 若需跨交换机通信,需配置**Trunk模式**并允许VLAN 1通过[^2]。 4. **验证连通性** ```bash ping 192.168.1.3 # 在服务器A执行 ping 192.168.1.2 # 在客户端C执行 ``` 5. **防火墙设置(可选)** 若使用`iptables`,开放VLAN接口的通信: ```bash sudo iptables -A INPUT -i eth0.1 -j ACCEPT sudo service iptables save # 保存规则[^3] ``` --- ### **注意事项** - **VLAN接口持久化**: 上述配置重启后会失效,需将命令写入`/etc/network/interfaces`(Debian)或`/etc/sysconfig/network-scripts/ifcfg-eth0.1`(RHEL)。 - **交换机兼容性**: 确保交换机支持IEEE 802.1Q VLAN协议。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

STHUDY

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

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

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

打赏作者

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

抵扣说明:

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

余额充值