linux网络编程

本文档展示了如何使用C语言实现基于TCP协议的简单客户端和服务端通信。客户端通过socket创建连接,发送'hello '字符串,并接收服务端响应。服务端则监听指定端口,接受客户端连接,读取并转换接收到的数据后回传给客户端。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现现简单客户端和服务端的通信(基于TCP)

客户端代码如下

//client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <pthread.h>

#define SERV_PORT 9527

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

int main(int argc, char *argv[])
{
    int connect_fd;
    char buf[BUFSIZ];

    /*-------------- 1.创建表示绑定本地地址信息的socket -----------------*/
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;        //协议
    server_addr.sin_port = htons(SERV_PORT); //字节顺序转换网络字节顺序
 
    
    if (argv[1])
    {   ////将点分十进制字符串转换为网络顺序IP地址
        server_addr.sin_addr.s_addr = inet_addr(argv[1]);
        //method2
        //inet_pton(AF_INET, "192.168.1.94", &server_addr.sin_addr.s_addr);
    }
    else
    {
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    }

    /*-------------------- 2.创建套接字对象 --------------------*/
    if ( (connect_fd = socket(AF_INET, SOCK_STREAM, 0))  == -1)
    {
        my_err("socket error");
    }
    /*-------------------- 3.尝试连接服务端 --------------------*/
    //1.param1: socket返回地文件描述符.
    //2.param2: socket储存连接地目的主机地址(包括IP地址和端口)
    //3.param3:目的主机地址的长度
    //4.如果连接成功返回0,失败则返回-1
    if (connect(connect_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
    {
        my_err("connect error");
    }

    while (1)
    {
        //write(connect_fd, "hello\n", 6);
        send(connect_fd, "hello\n", 6,0);
        sleep(3);
        int ret = read(connect_fd, buf, sizeof(buf));
        printf("ret = %d\n", ret);
        write(STDOUT_FILENO, buf, ret);//输出字符串
    }

    close(connect_fd);

    return 0;
}

服务端代码如下

//server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <pthread.h>
#include <ctype.h>

#define SERV_PORT 9527

void my_err(const char *str)
{
    perror(str);
    exit(1);
}
int main(int argc, char *argv[])
{
    int listen_fd, connect_fd;

    char buf[BUFSIZ], client_ip[1024];

    /*-------------- 1.创建表示绑定本地地址信息的sockaddr -----------------*/
    //根据不同地应用,sockaddr需要选用不同地类型,IPV4网络通信选用sockaddr_in
    struct sockaddr_in server_addr, client_addr;
    bzero(&server_addr,sizeof(server_addr));
    server_addr.sin_family = AF_INET;       //选择协议簇
    server_addr.sin_port = htons(SERV_PORT);//设置端口号
    
    if (argv[1])
    {
        ////将点分十进制字符串转换为网络顺序32位IP地址,大端模式
        server_addr.sin_addr.s_addr = inet_addr(argv[1]); //设置IP地址
    }
    else
    {
        ////否则设置为本地任意地址
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    }



    
    /*-------------------- 2.创建套接字对象 --------------------*/
    //param1:通信协议:IPV4协议簇
    //param2:socket地类型:SOCK——STREAM, 可靠地,面向连接地流socket,默认为TCP
    //param3:采用地协议:0,让系统自动选择默认协议
    //如果成功,则返回一个打开的soeket文件描述符,失败则返回-1
    if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        my_err("socket error");
    }

    /*------------------ 3.绑定本地ip地址和端口 -----------------*/
    //param1:用于绑定IP信息和端口信息地socket文件描述符
    //1.IP地址必须为本机IP地址
    //2.端口必须为一个没有被占用地本地端口
    if (bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
    {
        my_err("bind error");
    }

    /*----------------------- 4.监听网络 ---------------------*/
    //param1:绑定了IP信息和端口信息地socket文件描述符
    //param2:请求排队地最大长度
    if (listen(listen_fd, 128) == -1)
    {
        my_err("listen error");
    }
    /*------------------ 5.阻塞等待客户端连接响应 -----------------*/
    // param1:绑定了IP信息和端口信息地socket文件描述符
    // param2:用于存储客户端地IP地址和端口信息
    // 返回一个新的文件描述符来标识该连接。如果执行失败,则返回-1
    printf("wait for connect\n");
    socklen_t len_client = sizeof(client_addr);
    if ((connect_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &len_client)) == -1)
    {
        my_err("accept error");
    }
    else{
        //打印客户端信息
        printf("client : ip = %s, port = %d\n",
               inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, client_ip, sizeof(client_ip)),
               ntohs(client_addr.sin_port));
    }
    while (1)
    {
        //如果执行成功,则返回读取数据的大小,失败则返回-1
        int ret = read(connect_fd, buf, sizeof(buf));
        write(STDOUT_FILENO, buf, ret);
        sleep(3);
        for (int i = 0; i < ret; i++)
        {
            buf[i] = toupper(buf[i]);
        }
        //printf("ret = %d\n", ret);
        //如果执行成功,则返回发送数据地大小,失败则返回-1
        write(connect_fd, buf, ret);
    }

    close(listen_fd);
    close(connect_fd);
    return 0;
}

效果演示

服务端

服务端

客户端

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值