citta

下面分别以TCP、UDP为例介绍两者的流程图和代码实现:

  • TCP

1.流程图:

  和网上大部分的版本不同,我将TCP三次握手的过程画在了accpet之前,这也是在查阅一些资料发现三次握手会由内核自动完成,aceept只是从队列中取出已经建好的tcp连接,这一点可以在accept之前多加点等待时间验证。

2.代码实现:

  server端:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

#define SERVER_PORT 8888
#define SERVER_IP "192.168.1.100"

int main()
{
    // 1. 创建监听套接字
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == -1)
    {
        perror("fail fo socket!");
        return -1;
    }
    printf("create socket fd[%d] success!\n");

    // 2. 绑定监听套接字到本地IP和port
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(SERVER_PORT);
    inet_pton(AF_INET, SERVER_IP, &addr.sin_addr);
    int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    if (ret == -1)
    {
        perror("fail to bind!");
        return -2;
    }
    printf("bind success!\n");

    // 3. 设置监听
    ret = listen(fd, 128);
    if (ret == -1)
    {
        perror("fail to listen!");
        return -3;
    }
    printf("listen success!\n");

    // 4. 阻塞等待,等待连接到达,连接成功后返回通信用的套接字
    struct sockaddr_in c_addr;
    int c_addr_len = 0;
    int c_fd = accept(fd, (struct sockaddr*)&c_addr, &c_addr_len);
    if (c_fd == -1)
    {
        perror("fail to accept!");
        return -4;
    }
    printf("accept success!\n");

    // 5. 开始通信
    char buff[1024];
    char ip[32];
    memset(buff, 0, sizeof(buff));
    memset(ip, 0, sizeof(ip));
    int len = read(c_fd, buff, sizeof(buff));
    if (len > 0)
    {
        printf("client %s:%d >> %s\n", inet_ntop(AF_INET, &c_addr.sin_addr, ip , sizeof(ip)), ntohs(c_addr.sin_port), buff);
        write(c_fd, buff, len);
    }
    else if (len == 0)
    {
        printf("connect close!");
    }
    else
    {
        printf("connect fail!");
    }

    // 6. 关闭套接字
    close(fd);
    close(c_fd);
    return 0;
}

client端:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

#define SERVER_PORT 8888
#define SERVER_IP "192.168.1.100"

int main()
{
    // 1. 创建通信套接字
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == -1)
    {
        perror("fail fo socket!");
        return -1;
    }
    printf("create socket success!\n");

    // 2. 连接服务器
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(SERVER_PORT);
    inet_pton(AF_INET, SERVER_IP, &addr.sin_addr);
    int ret = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
    if (fd == -1)
    {
        perror("fail to connect!");
        return -2;
    }
    printf("connect success!\n");

    // 3. 通信
    char buff[1024];
    char ip[32];
    sprintf(buff, "Hello, this is a test connection with the server!");
    int len = send(fd, buff, strlen(buff) + 1, 0);
    memset(buff, 0, sizeof(buff));
    memset(ip, 0, sizeof(ip));
    len = recv(fd, buff, sizeof(buff), 0);
    if (len > 0)
    {
        printf("server %s:%d >> %s\n", inet_ntop(AF_INET, &addr.sin_addr, ip , sizeof(ip)), ntohs(addr.sin_port), buff);
    }
    else if (len == 0)
    {
        printf("connect close!\n");
    }
    else
    {
        perror("recv fail!\n");
    }

    // 4. 关闭套接字
    close(fd);
    return 0;
}

 

分类:

技术点:

相关文章: