linux系统编程(十②)RK3568 socket之 TCP 客户端的实现

开发环境

1、讯为RK3568开发板,下载了Ubuntu系统。

2、笔记本Windows下的VScode连接开发板。

3、网线连接开发板J13网口。

VSCode远程连接开发板:https://blog.csdn.net/u012507643/article/details/152666866?spm=1011.2124.3001.6209

UDP收发的流程:

创建socket->bind->connect->sendto/recvfrom/send/recv

一、用到的函数

函数参考前面写的一片博客,这里不复制过来了

https://blog.csdn.net/u012507643/article/details/153478108?sharetype=blogdetail&sharerId=153478108&sharerefer=PC&sharesource=u012507643&spm=1011.2480.3001.8118

二、直接看实际代码

复制代码
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <errno.h>


int main(int argc, char *argv[])
{
    int fd;
    int conn = 0;
    int ret = 0;
    char tx_buf[1024] = {"12324"}, rx_buf[1024] = {0};
    struct sockaddr_in cs;

    //SOCK_STREAM:TCP
    fd = socket(AF_INET, SOCK_STREAM, 0);

    inet_pton(AF_INET, "192.168.31.20", &cs.sin_addr);
    cs.sin_family = AF_INET;
    cs.sin_port = htons(8080);
    bind(fd, (const struct sockaddr *)&cs, sizeof(cs));

    while(1)
    {

        if (conn == 0)
        {
            if (connect(fd, (const struct sockaddr *)&cs, sizeof(cs)) < 0)
            {
                //printf("connect failed\n");
            }
            else
            {
                printf("connectted server\n");
                conn = 1;
            }
        }
        else
        {
            // struct tcp_info info;
            int len = sizeof(cs);

            /* 这里才是真正的数据 */
            ret = recv(fd, rx_buf, sizeof(rx_buf) - 1, MSG_DONTWAIT);
            if (ret > 0)
            {
                    printf("recv data:%s, len=%d\n", rx_buf, ret);
                    // printf("input data:\n");
                    // scanf("%s", tx_buf);
                    if (sendto (fd, rx_buf, ret, MSG_DONTWAIT, (struct sockaddr *)&cs, sizeof(cs)) < 0)
                    {
                        
                        printf("server abroad\n");
                        conn = 0;
                    }
                    memset(tx_buf, 0, sizeof(tx_buf));
                    memset(rx_buf, 0 ,sizeof(rx_buf));
            }

            /* 这里仅仅作为探针,看下连接是否断开 */
            ret = recv(fd, rx_buf, sizeof(rx_buf) - 1, MSG_PEEK);
            if ((ret > 0) || ((ret == -1) && (errno == EAGAIN)))
            {
                continue;
            }
            else
            {
                printf("server abroad\n");
                conn = 0;
                close(fd);
                fd = socket(AF_INET, SOCK_STREAM, 0);
            }
        }
    }
    close(fd);

    return 0;
}

三、测试结果

1、测试连接

2、测试断开重连【网络助手断开重新侦听】

3、测试收发数据

四、总结

1、这里增加判断远程是否断开:

使用recv() 函数的MSG_PEEK选项,使用这个选项可以"偷看(peek)"一下接收队列的数据。所谓"偷看",就是recv()不从接收队列中把数据移除,因此下一次调用recv()函数还会接收到此数据。

当TCP连接处于已建立Established状态时,如果接收队列中有数据,recv()函数返回实际接收的字节数;如果接收队列中没有数据但是TCP连接没有断开,recv() 函数返回-1,并且把errno设置为EAGAIN。其余情况下表示TCP连接已经断开。

所以上面我使用了两次的recv函数,一个是接收数据用,一个是判断是否断开了。

2、重连时候需要close掉上一次的套接字描述符,否则直接connect是失败的。

由于本人也是刚学,写的不好,也不规范,有错误的地方望前辈指正,以免误入歧途。

相关推荐
HLC++11 小时前
Linux的进程间通信
android·linux·服务器
华清远见IT开放实验室13 小时前
实验室建设案例 | 石家庄科技信息职业学院嵌入式实验室——从底层硬件到系统应用,一所应用型高校的嵌入式人才培养这样落地
linux·arm开发·stm32·嵌入式硬件·高校·实验室建设
groundhappy15 小时前
idalib安装和codex ida-mcp配置
linux·开发语言·python
通信小小昕16 小时前
Ubuntu 26.04 中文输入法安装
linux·运维·ubuntu
张小姐的猫17 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
栩栩云生17 小时前
AI 写代码犯的错,早被写进了错题集
linux·安全·ai编程
imc.1119 小时前
linux基础IO
linux·运维·服务器
BelongPanda20 小时前
Linux Nginx 纯手动 Let‘s Encrypt 泛域名证书配置教程
linux·nginx
酷可达拉斯21 小时前
Linux操作系统-shell编程(0)
linux·运维·服务器·python·云计算
2301_7779983421 小时前
Linux中断机制:操作系统如何高效运行
linux·运维·服务器