linux socket通信

linux socket通信

服务器端

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <ctype.h>


int main(int argc, const char* argv[])
{
    // 创建用于监听的套节字
    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd == -1)
    {
        perror("socket error");
        exit(1);
    }

    // 绑定
    struct sockaddr_in serv_addr;
    // init
    memset(&serv_addr, 0, sizeof(serv_addr));
    // bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET; // 地址族协议  ipv4
    serv_addr.sin_port = htons(9999);   // 本地端口, 需要转换为大端
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  // 0 是用本机的任意IP

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

    // 设置监听
    ret = listen(lfd, 64);
    if(ret == -1)
    {
        perror("listen error");
        exit(1);
    }

    // 等待并接受连接请求
    struct sockaddr_in cline_addr;
    socklen_t clien_len = sizeof(cline_addr);
    int cfd = accept(lfd, (struct sockaddr*)&cline_addr, &clien_len);
    if(cfd == -1)
    {
        perror("accept error");
        exit(1);
    }
    
    char ipbuf[64];
    // int -> char*
    printf("cliient ip: %s, port: %d\n",
           inet_ntop(AF_INET, &cline_addr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),
           ntohs(cline_addr.sin_port));

    // 通信
    while(1)
    {
        // 先接收数据
        char buf[1024] = {0};
        int len = read(cfd, buf, sizeof(buf));
        if(len == -1)
        {
            perror("read error");
            break;
        }
        else if(len > 0)
        {
            // 顺利读出了数据
            printf("read buf = %s\n", buf);
            // 小写 -》 大写
            for(int i=0; i<len; ++i)
            {
                buf[i] = toupper(buf[i]);
            }
            printf(" -- toupper: %s\n", buf);

            // 数据发送给客户端
            write(cfd, buf, strlen(buf)+1);
        }
        else if( len == 0 )
        {
            printf("client disconnect ...\n");
            break;
        }
    }

    close(lfd);
    close(cfd);

    return 0;
}

客户端

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <fcntl.h>

// tcp client
int main(int argc, const char* argv[])
{
    if(argc <2){
        printf("eg: ./a.out prot\n");
        exit(1);
    }
    int port = atoi(argv[1]);
    // 创建套接字
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if(fd == -1)
    {
        perror("socket error");
        exit(1);
    }

    // 连接服务器
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);//9999
    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr.s_addr);
    int ret = connect(fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    if(ret == -1)
    {
        perror("connect error");
        exit(1);
    }

    // 通信
    while(1)
    {
        // 写数据
        // 接收键盘输入
        char buf[1024];
        printf("请输入要发送的字符串:\n");
        fgets(buf, sizeof(buf), stdin);
        // 发送给服务器
        write(fd, buf, strlen(buf)+1);

        // 接收服务器端的数据
        int len = read(fd, buf, sizeof(buf));
        if(len == -1){
            perror("read error");
            exit(1);
        }else if(len ==0){
            printf("服务器端关闭了连接\n");
            break;
        }else{
            printf("rec buf : \n");
            printf("read buf = %s, len = %d\n", buf, len);
        }
        close(fd);
    }
    return 0;
}

测试

编译

$ gcc tcp_server.c -o server
$ gcc tcp_client.c -o client

启动服务端

$ ./server 
cliient ip: 127.0.0.1, port: 50602
read buf = hello

 -- toupper: HELLO

client disconnect ...

启动客户端

$ ./client 9999
请输入要发送的字符串:
hello
rec buf : 
read buf = HELLO
, len = 7
请输入要发送的字符串:
world
read error: Bad file descriptor

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值