【Linux系统编程】TCP实现--socket

使用套接字socket实现服务器和客户端之间的TCP通信。

流程如下:

实现代码:

c 复制代码
/* server.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <errno.h>
#include <ctype.h>

#define SERV_PORT 9527

void sys_err(const char *str)
{
    perror(str);
    exit(1);
}


int main(int argc, char *argv[])
{
    struct sockaddr_in serv_addr, client_addr;
    socklen_t client_addr_len;
    char buf[BUFSIZ], client_IP[1024];
    //1. 创建监听套接字
    int lfd = socket(AF_INET,  //IPV4
                    SOCK_STREAM, 
                    0);
    if(lfd == -1) //check RETURN VALUE
    {
        sys_err("socket error");
    }
    //2. 绑定本地的IP地址和端口号
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERV_PORT);
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    int ret = bind(lfd,  (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    if(ret == -1)
    {
        sys_err("bind error");
    }

    //3. 设置监听
    int ret_listen = listen(lfd, 128);
    if(ret_listen == -1)
    {
        sys_err("listen error");
    }
    
    //4. 阻塞等待,连接的到达,连接成功后返回通信用的套接字
    client_addr_len = sizeof(client_addr);
    int cfd = accept(lfd, (struct sockaddr*)&client_addr, &client_addr_len);
    if(cfd == -1)
    {
        sys_err("accept error");
    }
    printf("client ip is %s, port is %d\n",
             inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, client_IP, sizeof(client_IP)),
             ntohs(client_addr.sin_port));

    //5. 开始通信
    while(1)
    {
        ssize_t ret_acc = read(cfd, buf, sizeof(buf));
        write(STDOUT_FILENO, buf, ret_acc);

        for(int i = 0; i < ret_acc; i++)
        {
            buf[i] = toupper(buf[i]);
        }
        write(cfd, buf, ret_acc);
    }

    close(lfd);
    close(cfd);

    return 0;
}
c 复制代码
/* client.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <errno.h>
#include <ctype.h>

#define SERV_PORT 9527

void sys_err(const char *str)
{
    perror(str);
    exit(1);
}


int main(int argc, char *argv[])
{
    int cfd;
    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERV_PORT);
    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr.s_addr);
    char buf[BUFSIZ];
    int cnt = 10;

    //1. 创建监听套接字
    cfd = socket(AF_INET, SOCK_STREAM, 0);
    if(cfd == -1) 
    {
        sys_err("socket error");
    }

    int ret = connect(cfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    if(ret != 0)
    {
        sys_err("connect error");
    }

    while(cnt--)
    {
        write(cfd, "hello\n", 6);
        ret = read(cfd, buf, sizeof(buf));
        write(STDERR_FILENO, buf, ret);
        sleep(1);

    }

    close(cfd);

    return 0;
}

实验现象

客户端向服务器发送10次hello,接收到服务器发来的10次大写HELLO;服务器首先打印IP地址和端口号,随后打印收到的10次由客户端传来的hello。

相关推荐
文青小兵几秒前
Linux云计算——docker compose haibor elfk (四)
linux·服务器·docker·云计算
思麟呀6 分钟前
C++11并发编程:互斥锁
linux·开发语言·c++·windows
顺风尿一寸9 分钟前
深度解析 Linux touch 命令:从用户输入到磁盘 Inode 的完整旅程
linux
j_xxx404_17 分钟前
Linux 线程日志系统设计:从策略模式、RAII 到 pthread 线程安全与内核写入路径|附源码
linux·运维·服务器·开发语言·c++·人工智能·策略模式
明天…ling20 分钟前
CentOS 7 安装 Docker 踩坑全记录(含 sudo 权限、yum 源失效、命令报错解决方案)
linux·docker·centos
江华森20 分钟前
Linux 内核调优 + TCP/IP 协议栈深度解析 + 低延迟网络优化
linux·网络·tcp/ip
范范@21 分钟前
Python进阶 网络编程笔记-多进程
网络·笔记·python
学Linux的语莫31 分钟前
deepagent知识
linux·运维·服务器
步十人34 分钟前
epoll——I/O多路复用技术
linux·数据库·redis
浮生若城1 小时前
Linux库制作与原理(1):静态库、动态库和ELF文件
linux·运维·服务器