网络编程(day2)——TCP模型

服务器端:

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>

#define ERR_MSG(msg)                              \
    do {                                          \
        fprintf(stderr, "line : %d\n", __LINE__); \
        perror(msg);                              \
    } while (0)

#define IP "192.168.0.122"
#define PORT 8888

int main(int argc, char const* argv[])
{
    // 1.创建流式套接字
    int sfd;
    if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        ERR_MSG("socket error");
        return -1;
    }
    printf("socket successful __%d__\n", __LINE__);

    // 允许端口快速被重复使用,当检测到该端口号没有被进程正常占用的时候,允许端口快速被新的进程占用覆盖
    int reuse = 1;
    if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
        ERR_MSG("setsockopt error");
        return -1;
    }
    printf("允许端口快速重用\n");

    // 2.绑定服务器的IP地址和端口
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
    sin.sin_addr.s_addr = inet_addr(IP);

    if (bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
        ERR_MSG("bind error");
        return -1;
    }
    printf("bind successful __%d__\n", __LINE__);

    // 3.将套接字设置为被动监听状态
    if (listen(sfd, 128) < 0) {
        ERR_MSG("listen error");
        return -1;
    }
    printf("listen successful __%d__\n", __LINE__);

    // 4.获取连接成功后的套接字
    int newfd;
    struct sockaddr_in cin;
    socklen_t addrlen = sizeof(cin);
    if ((newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen)) < 0) {
        ERR_MSG("accept error");
        return -1;
    }
    printf("client-[%s : %d] newfd = %d  连接成功  __%d__\n",
        inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, __LINE__);

    char buf[128] = { 0 };
    ssize_t res;

    while (1) {

        // 发送数据
        printf("input >");
        memset(buf, 0, sizeof(buf));
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = '\0';
        if (send(newfd, buf, strlen(buf), 0) < 0) {
            ERR_MSG("send error");
            continue;
        }
        printf("send successful\n");

        // 5.读取数据
        memset(buf, 0, sizeof(buf));
        res = recv(newfd, buf, sizeof(buf), 0);
        if (res < 0) {
            ERR_MSG("recv error");
            return -1;
        } else if (res == 0) {
            printf("client-[%s : %d] newfd = %d  客户端下线  __%d__\n",
                inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, __LINE__);
            break;
        }
        printf("client-[%s : %d] newfd = %d  buf = %s  __%d__\n",
            inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, buf, __LINE__);
    }

    return 0;
}

客户端:

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>

#define ERR_MSG(msg)                              \
    do {                                          \
        fprintf(stderr, "line : %d\n", __LINE__); \
        perror(msg);                              \
    } while (0)

#define IP "192.168.0.122"
#define PORT 8888

int main(int argc, char const* argv[])
{
    // 1.创建流式套接字
    int cfd;
    if ((cfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        ERR_MSG("socket error");
        return -1;
    }
    printf("socket successful __%d__\n", __LINE__);

    // 2.绑定客户端的IP和端口(非必须,此处不绑定)

    // 3.连接服务器
    // 通用地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
    sin.sin_addr.s_addr = inet_addr(IP);
    if (connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
        ERR_MSG("connect error");
        return -1;
    }
    printf("服务器连接成功!\n");

    char buf[128] = { 0 };
    ssize_t res;

    while (1) {
        // 读取数据
        memset(buf, 0, sizeof(buf));
        res = recv(cfd, buf, sizeof(buf), 0);
        if (res < 0) {
            ERR_MSG("recv error");
            return -1;
        } else if (res == 0) {
            printf("服务器下线!\n");
            break;
        }
        printf("read buf = %s  __%d__\n", buf, __LINE__);

        // 发送数据
        printf("input >");
        memset(buf, 0, sizeof(buf));
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = '\0';
        if (send(cfd, buf, strlen(buf), 0) < 0) {
            ERR_MSG("send error");
            break;
        }
        printf("send successful\n");
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值