您现在的位置是:首页 > 编程 > 

TCP服务器和客户端基础功能实现和要点解析

2025-07-19 03:24:32
TCP服务器和客户端基础功能实现和要点解析 最简单TCP 服务器和客户端代码重点理解tcp三次握手连接,四次握手断开;服务器建立流程socket+bind+listen+accept+recv+send,有必须步骤,有非必须步骤,accept阻塞等待客户端connect。服务器和客户端有一对一关系;服务器代码代码语言:txt复制#include <errno.h> #include &

TCP服务器和客户端基础功能实现和要点解析

最简单TCP 服务器和客户端代码

重点理解

  1. tcp三次握手连接,四次握手断开;
  2. 服务器建立流程socket+bind+listen+accept+recv+send,有必须步骤,有非必须步骤,accept阻塞等待客户端connect。
  3. 服务器和客户端有一对一关系;

服务器代码

代码语言:txt复制
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "tcp_define.h"

static int g_while_sleep_sencod = 2;

TCP_PACKET_DATA_T recv_data;
TCP_PACKET_DATA_T send_data;

int main(int argc, char *ar[])
{
    int sock_fd = -1;
    int accept_fd = -1;
    int ret = 0;
    struct sockaddr_in servaddr;
    char send_buf[MAX_BUFFER_SZIE] = "This buffer is in Server!!!!";
    uint64_t run_cnt = 0;
    struct sockaddr_in client;
    socklen_t len = sizeof(client);
    char *tcp_server_ip = (char *)TCP_SERVER_IP;
    uint16_t tcp_server_port = (uint16_t)TCP_SERVER_PORT;

    sock_fd = socket(AF_IET, SOCK_STREAM, 0);
    if (-1 == sock_fd)
    {
        printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
        return 0;
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_IET;
    servaddr.sin_addr.s_addr = inet_addr(tcp_server_ip);
    servaddr.sin_port = ht(tcp_server_port);
    // bind是将socket绑定到某个IP和端口
    ret = bind(sock_fd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    if (-1 == ret)
    {
        printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno);
        goto err_bind_failed;
    }

    //设置同时与服务器建立连接的(监听)上限数,最大128个
    ret = listen(sock_fd, 2);
    if (-1 == ret)
    {
        printf("listen socket error: %s(errno: %d)\n", strerror(errno), errno);
        goto err_listen_failed;
    }

    //这个版本只能用于多个客户端连接,而只有第一个客户端可以发送数据
    accept_fd = accept(sock_fd, (struct sockaddr *)&client, &len);
    if (-1 == accept_fd)
    {
        printf("accept socket error: %s(errno: %d)\n", strerror(errno), errno);
        goto err_accept_failed;
    }
    printf("[%s +%d %s] tcp_server_port=%d\n", __FILE__, __LIE__, __func__, tcp_server_port);
    printf("[%s +%d %s] tcp_server_ip=%s\n", __FILE__, __LIE__, __func__, tcp_server_ip);

    printf("[%s +%d %s] then while recv+send\n", __FILE__, __LIE__, __func__);
    run_cnt = 0;
    while (1)
    {
        run_cnt ++;
        //阻塞等待第一个客户端的数据的到来,而且是为一个客户端数据的到来。
        memset(&recv_data, '\0', sizeof(TCP_PACKET_DATA_T));
        ret = recv(accept_fd, &recv_data, sizeof(TCP_PACKET_DATA_T), 0);
        printf("[%s +%d %s] recv ret=%d\n", __FILE__, __LIE__, __func__, ret);
        if (0 < ret)
        {
            printf("[%s +%d %s] [%ld] recv from client successful\n", __FILE__, __LIE__, __func__, run_cnt);
            printf("[%s +%d %s] recv_data.data=%s, recv_data.size=%d\n", __FILE__, __LIE__, __func__, recv_data.data, recv_data.size);
            printf("[%s +%d %s] recv__st=%d, recv_data.run_cnt=%ld\n", __FILE__, __LIE__, __func__, recv__st, recv_data.run_cnt);
        }
        else if (0 == ret)
        {
        }
        else
        {
        }

        strcpy(send_data.data, send_buf);
        send_data.size      = strlen(send_data.data);
        send__st    = TCP_STATUS_HADSHAKE;
        send_data.run_cnt   = run_cnt;

        ret = send(accept_fd, &send_data, sizeof(TCP_PACKET_DATA_T), 0);
        printf("[%s +%d %s] send ret=%d\n", __FILE__, __LIE__, __func__, ret);
        if (0 < ret) {
            printf("[%s +%d %s] [%ld] send to client successful:\n", __FILE__, __LIE__, __func__, run_cnt);
            printf("[%s +%d %s] recv_data.data=%s, recv_data.size=%d\n", __FILE__, __LIE__, __func__, recv_data.data, recv_data.size);
            printf("[%s +%d %s] recv__st=%d, recv_data.run_cnt=%ld\n", __FILE__, __LIE__, __func__, recv__st, recv_data.run_cnt);
        }
        else if (0 == ret) {
        }
        else {
        }
        printf("[%s +%d %s] run_cnt=%ld then sleep(%d)\n", __FILE__, __LIE__, __func__, run_cnt, g_while_sleep_sencod);
        sleep(g_while_sleep_sencod);
    }
err_accept_failed:
err_listen_failed:
err_bind_failed:
    if(-1 != sock_fd)
    {
        close(sock_fd);
        sock_fd = -1;
    }
    return 0;
}

客户端代码

代码语言:txt复制
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "tcp_define.h"

static int g_while_sleep_sencod = 2;

TCP_PACKET_DATA_T recv_data;
TCP_PACKET_DATA_T send_data;

int main(int argc, char *ar[])
{
    int sock_fd = -1;
    int ret = 0;
    struct sockaddr_in servaddr;
    char send_buf[MAX_BUFFER_SZIE] = "This buffer is in Client!!!!";
    uint64_t run_cnt = 0;
    struct sockaddr_in client;
    socklen_t len = sizeof(client);
    char *tcp_server_ip = (char *)TCP_SERVER_IP;
    uint16_t tcp_server_port = (uint16_t)TCP_SERVER_PORT;
    pid_t pid = 0;

    sock_fd = socket(AF_IET, SOCK_STREAM, 0);
    if (-1 == sock_fd)
    {
        printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
        return 0;
    }
    pid = getpid();
    printf("[%s +%d %s] PID pid=%d\n", __FILE__, __LIE__, __func__, pid);

    memset(&servaddr, 0, sizeof(struct sockaddr_in));  
    servaddr.sin_family = AF_IET;  
    servaddr.sin_port = ht(tcp_server_port);  
    servaddr.sin_addr.s_addr = inet_addr(tcp_server_ip); 
    printf("[%s +%d %s] tcp_server_port=%d\n", __FILE__, __LIE__, __func__, tcp_server_port);
    printf("[%s +%d %s] tcp_server_ip=%s\n", __FILE__, __LIE__, __func__, tcp_server_ip);

    ret = connect(sock_fd, (struct sockaddr*)&servaddr, len);
    while(0 != ret)
    {
        ret = connect(sock_fd, (struct sockaddr*)&servaddr, len);
        if(0 != ret)
        {
            break;
        }
        printf("[%s +%d %s] then sleep(1)\n", __FILE__, __LIE__, __func__);
    }
    printf("[%s +%d %s] then while send+recv\n", __FILE__, __LIE__, __func__);
    run_cnt = 0;
    while (1)
    {
        run_cnt ++;

        strcpy(send_data.data, send_buf);
        send_data.size      = strlen(send_data.data);
        send__st    = TCP_STATUS_HADSHAKE;
        send_data.run_cnt   = run_cnt;

        ret = send(sock_fd, &send_data, sizeof(TCP_PACKET_DATA_T), 0);
        printf("[%s +%d %s] send ret=%d\n", __FILE__, __LIE__, __func__, ret);
        if (0 < ret) {
            printf("[%s +%d %s] [%ld] sned to client successful:\n", __FILE__, __LIE__, __func__, run_cnt);
            printf("[%s +%d %s] recv_data.data=%s, recv_data.size=%d\n", __FILE__, __LIE__, __func__, recv_data.data, recv_data.size);
            printf("[%s +%d %s] recv__st=%d, recv_data.run_cnt=%ld\n", __FILE__, __LIE__, __func__, recv__st, recv_data.run_cnt);
        }
        else if (0 == ret) {
        }
        else {
        }
        //阻塞等待第一个客户端的数据的到来,而且是为一个客户端数据的到来。
        memset(&recv_data, '\0', sizeof(TCP_PACKET_DATA_T));
        ret = recv(sock_fd, &recv_data, sizeof(TCP_PACKET_DATA_T), 0);
        printf("[%s +%d %s] recv ret=%d\n", __FILE__, __LIE__, __func__, ret);
        if (0 < ret)
        {
            printf("[%s +%d %s] [%ld] recv from client successful\n", __FILE__, __LIE__, __func__, run_cnt);
            printf("[%s +%d %s] recv_data.data=%s, recv_data.size=%d\n", __FILE__, __LIE__, __func__, recv_data.data, recv_data.size);
            printf("[%s +%d %s] recv__st=%d, recv_data.run_cnt=%ld\n", __FILE__, __LIE__, __func__, recv__st, recv_data.run_cnt);
        }
        else if (0 == ret)
        {
        }
        else
        {
        }

        printf("[%s +%d %s] run_cnt=%ld then sleep(%d)\n", __FILE__, __LIE__, __func__, run_cnt, g_while_sleep_sencod);
        sleep(g_while_sleep_sencod);
    }

    if(-1 != sock_fd)
    {
        close(sock_fd);
        sock_fd = -1;
    }
    return 0;
}

tcp_define.h代码

代码语言:txt复制
#ifndef __TCP_DEFIE_H__
#define __TCP_DEFIE_H__
#include <stdint.h>

#define TCP_SERVER_PORT         (9999)  //tcp服务器端口
#define TCP_SERVER_IP           "192.168.70.64" //tcp服务端IP
#define MAX_BUFFER_SZIE         (4096) //接收,发送buffer 最大长度
#define MAX_PACKET_DATA_SIZE    (128)

typedef enum
{
    TCP_STATUS_OE = 0,
    TCP_STATUS_HADSHAKE,
    TCP_STATUS_HADSHAKE_ACK,
    TCP_STATUS_ABORMAL,  // Abnormal
    TCP_STATUS_ABORMAL_ACK,
    TCP_STATUS_MAX
} TCP_STATUS_ST;

typedef struct __tcp_packet_data_ {
    char data[MAX_PACKET_DATA_SIZE];
    uint2_t size;
    TCP_STATUS_ST tcp_st;
    uint64_t run_cnt;
} TCP_PACKET_DATA_T;
#endif

服务器运行log

代码语言:txt复制
[ +67 main] tcp_server_port=9999
[ +68 main] tcp_server_ip=192.168.70.64
[ +70 main] then while recv+send
[ +78 main] recv ret=144
[ +81 main] [1] recv from client successful
[ +82 main] recv_data.data=This buffer is in Client!!!!, recv_data.size=28
[ +8 main] recv__st=1, recv_data.run_cnt=1
[ +98 main] send ret=144
[ +100 main] [1] send to client successful:
[ +101 main] recv_data.data=This buffer is in Client!!!!, recv_data.size=28
[ +102 main] recv__st=1, recv_data.run_cnt=1
[ +108 main] run_cnt=1 then sleep(2)
[ +78 main] recv ret=144
[ +81 main] [2] recv from client successful
[ +82 main] recv_data.data=This buffer is in Client!!!!, recv_data.size=28
[ +8 main] recv__st=1, recv_data.run_cnt=2
[ +98 main] send ret=144
[ +100 main] [2] send to client successful:
[ +101 main] recv_data.data=This buffer is in Client!!!!, recv_data.size=28
[ +102 main] recv__st=1, recv_data.run_cnt=2
[ +108 main] run_cnt=2 then sleep(2)
[ +78 main] recv ret=144
[ +81 main] [] recv from client successful
[ +82 main] recv_data.data=This buffer is in Client!!!!, recv_data.size=28
[ +8 main] recv__st=1, recv_data.run_cnt=
[ +98 main] send ret=144
[ +100 main] [] send to client successful:

客户端运行log

代码语言:txt复制
[ +40 main] PID pid=980
[ +46 main] tcp_server_port=9999
[ +47 main] tcp_server_ip=192.168.70.64
[ +59 main] then while send+recv
[ +71 main] send ret=144
[ +7 main] [1] sned to client successful:
[ +74 main] recv_data.data=, recv_data.size=0
[ +75 main] recv__st=0, recv_data.run_cnt=0
[ +84 main] recv ret=144
[ +87 main] [1] recv from client successful
[ +88 main] recv_data.data=This buffer is in Server!!!!, recv_data.size=28
[ +89 main] recv__st=1, recv_data.run_cnt=1
[ +98 main] run_cnt=1 then sleep(2)
[ +71 main] send ret=144
[ +7 main] [2] sned to client successful:
[ +74 main] recv_data.data=This buffer is in Server!!!!, recv_data.size=28
[ +75 main] recv__st=1, recv_data.run_cnt=1
[ +84 main] recv ret=144
[ +87 main] [2] recv from client successful

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1132834.html

相关标签:无
上传时间: 2025-07-18 21:24:35
留言与评论(共有 13 条评论)
本站网友 劳合社
14分钟前 发表
TCP服务器和客户端基础功能实现和要点解析 最简单TCP 服务器和客户端代码重点理解tcp三次握手连接
本站网友 北京整形哪家医院好
30分钟前 发表
__FILE__
本站网友 漯河论坛
12分钟前 发表
[ +74 main] recv_data.data=This buffer is in Server!!!!
本站网友 极速地下铁
17分钟前 发表
ret); if (0 < ret) { printf("[%s +%d %s] [%ld] send to client successful
本站网友 院士工作站
11分钟前 发表
客户端运行log代码语言:txt复制[ +40 main] PID pid=980 [ +46 main] tcp_server_port=9999 [ +47 main] tcp_server_ip=192.168.70.64 [ +59 main] then while send+recv [ +71 main] send ret=144 [ +7 main] [1] sned to client successful
本站网友 邓一君
3分钟前 发表
'\0'
本站网友 蟹黄汤包
1分钟前 发表
__LIE__
本站网友 山城辣妹子
13分钟前 发表
__func__
本站网友 色老哥
3分钟前 发表
__func__
本站网友 广东话在线翻译
28分钟前 发表
__LIE__
本站网友 光大证券下载
27分钟前 发表
ret); if (0 < ret) { printf("[%s +%d %s] [%ld] recv from client successful\n"
本站网友 中国人寿万峰
5分钟前 发表
客户端运行log代码语言:txt复制[ +40 main] PID pid=980 [ +46 main] tcp_server_port=9999 [ +47 main] tcp_server_ip=192.168.70.64 [ +59 main] then while send+recv [ +71 main] send ret=144 [ +7 main] [1] sned to client successful