【MPlayer的源码】【字幕合成源码】【unity canvas源码】csock源码

时间:2024-12-28 22:24:00 来源:有源码么 分类:百科

1.linux下用c语言编写局域网聊天工具
2.linux内核通信核心技术:Netlink源码分析和实例分析
3.【tcp】关于tcp socket出现的“connection reset by peer”和“broken pipe”
4.liux c socket编程,在main返回后出现 stack smash detected

csock源码

linux下用c语言编写局域网聊天工具

       /*服务器*/

       #include <stdio.h>

       #include <stdlib.h>

       #include <errno.h>

       #include <string.h>

       #include <sys/types.h>

       #include <netinet/in.h>

       #include <sys/socket.h>

       #include <sys/wait.h>

       #define SERVPORT

       #define BACKLOG

       #define MAX(a,b) ((a)>(b)?(a):(b))

       void str_echo(int);

       void server()

       {

        int sockfd,client_fd;

        struct sockaddr_in my_addr;

        struct sockaddr_in remote_addr;

        socklen_t sin_size;

        if((sockfd=socket(AF_INET,SOCK_STREAM,0))== -1)

        {

        perror("socket create error!");

        exit(1);

        }

        my_addr.sin_family=AF_INET;

        my_addr.sin_port=htons(SERVPORT);

        my_addr.sin_addr.s_addr=INADDR_ANY;

        bzero(&(my_addr.sin_zero),8);

        if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)

        {

        perror("bind error!");

        exit(1);

        }

        if(listen(sockfd,BACKLOG)==-1)

        {

        perror("listen error!");

        exit(1);

        }

        while(1)

        {

        sin_size=sizeof(struct sockaddr_in);

        if((client_fd=accept(sockfd,(struct sockaddr *)&remote_addr,&sin_size))==-1)

        {

        perror("accept error!");

        continue;

        }

        printf("received a connection from %s\n",inet_ntoa(remote_addr.sin_addr));

        if(!fork())

        {

        close(sockfd);

        str_echo(client_fd);

        exit(0);

        }

        close(client_fd);

        }

       }

       void str_echo(int sockfd)

       {

        int maxfd;

        char sendbuf[]={ 0};

        char recvbuf[]={ 0};

        fd_set rfds;

        while(1)

        {

        FD_SET(0,&rfds);

        FD_SET(sockfd,&rfds);

        maxfd=MAX(0,sockfd)+1;

        select(maxfd,&rfds,NULL,NULL,NULL);

        if(FD_ISSET(sockfd,&rfds))

        {

        bzero(recvbuf,);

        recv(sockfd,recvbuf,,0);

        printf("C:%s\n",recvbuf);

        }

        if(FD_ISSET(0,&rfds))

        {

        read(0,sendbuf,);

        send(sockfd,sendbuf,strlen(sendbuf),0);

        bzero(sendbuf,);

        }

        }

       }

       int main()

       {

        server();

        return 0;

       }

       /*客户端*/

       #include <stdio.h>

       #include <stdlib.h>

       #include <errno.h>

       #include <string.h>

       #include <netdb.h>

       #include <sys/types.h>

       #include <netinet/in.h>

       #include <sys/socket.h>

       #define SERVPORT

       #define MAXSIZE

       #define MAX(a,b) ((a)>(b)?(a):(b))

       void client(int argc,char **argv)

       {

        int sockfd,maxfd;

        char sendbuf[MAXSIZE]={ 0};

        char recvbuf[MAXSIZE]={ 0};

       // struct hostent *host;

        struct sockaddr_in serv_addr;

        fd_set rfds;

       /* if(argc<2)

        {

        fprintf(stderr,"Please enter the sserver's name!\n");

        exit(1);

        }

        if((host=gethostbyname(argv[1]))==NULL)

        {

        herror("get host by name error!\n");

        exit(1);

        }

       */

        if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)

        {

        perror("socket creat error!\n");

        exit(1);

        }

        serv_addr.sin_family=AF_INET;

        serv_addr.sin_port=htons(SERVPORT);

       // serv_addr.sin_addr=*((struct in_addr *)host->h_addr);

        serv_addr.sin_addr.s_addr=inet_addr(".0.0.1");

        bzero(&(serv_addr.sin_zero),8);

        if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)

        {

        perror("connection error!\n");

        exit(1);

        }

        FD_ZERO(&rfds);

        while(1)

        {

        FD_SET(0,&rfds);

        FD_SET(sockfd,&rfds);

        maxfd=MAX(0,sockfd)+1;

        select(maxfd,&rfds,NULL,NULL,NULL);

        if(FD_ISSET(sockfd,&rfds))

        {

        bzero(recvbuf,MAXSIZE);

        recv(sockfd,recvbuf,MAXSIZE,0);

        printf("S:%s\n",recvbuf);

        }

        if(FD_ISSET(0,&rfds))

        {

        fgets(sendbuf,MAXSIZE,stdin);

        send(sockfd,sendbuf,strlen(sendbuf),0);

        bzero(sendbuf,MAXSIZE);

        }

        }

       // close(sockfd);

       }

       int main(int argc,char **argv)

       {

        client(argc,argv);

        return 0;

       }

linux内核通信核心技术:Netlink源码分析和实例分析

       Linux内核通信核心技术:Netlink源码分析和实例分析

       什么是netlink?Linux内核中一个用于解决内核态和用户态交互问题的机制。相比其他方法,netlink提供了更安全高效的交互方式。它广泛应用于多种场景,例如路由、用户态socket协议、MPlayer的源码防火墙、netfilter子系统等。

       Netlink内核代码走读:内核代码位于net/netlink/目录下,包括头文件和实现文件。头文件在include目录,提供了辅助函数、宏定义和数据结构,字幕合成源码对理解消息结构非常有帮助。关键文件如af_netlink.c,其中netlink_proto_init函数注册了netlink协议族,使内核支持netlink。

       在客户端创建netlink socket时,使用PF_NETLINK表示协议族,unity canvas源码SOCK_RAW表示原始协议包,NETLINK_USER表示自定义协议字段。sock_register函数注册协议到内核中,以便在创建socket时使用。

       Netlink用户态和内核交互过程:主要通过socket通信实现,包括server端和client端。Centernet源码讲解netlink操作基于sockaddr_nl协议套接字,nl_family制定协议族,nl_pid表示进程pid,nl_groups用于多播。消息体由nlmsghdr和msghdr组成,用于发送和接收消息。南宫28源码内核创建socket并监听,用户态创建连接并收发信息。

       Netlink关键数据结构和函数:sockaddr_nl用于表示地址,nlmsghdr作为消息头部,msghdr用于用户态发送消息。内核函数如netlink_kernel_create用于创建内核socket,netlink_unicast和netlink_broadcast用于单播和多播。

       Netlink用户态建立连接和收发信息:提供测试例子代码,代码在github仓库中,可自行测试。核心代码包括接收函数打印接收到的消息。

       总结:Netlink是一个强大的内核和用户空间交互方式,适用于主动交互场景,如内核数据审计、安全触发等。早期iptables使用netlink下发配置指令,但在iptables后期代码中,使用了iptc库,核心思路是使用setsockops和copy_from_user。对于配置下发场景,netlink非常实用。

       链接:内核通信之Netlink源码分析和实例分析

【tcp】关于tcp socket出现的“connection reset by peer”和“broken pipe”

       åœ¨socket通信过程中,经常发现客户端或者服务器的日志中出现“broken pipe”或者“connection reset by peer”的错误提示。

        以前一直以为自己理解了这两个错误异常提示所包含的意义,而实际理解完全错误。

        我的错误理解和下面这段来自blogspot的表述差不多:

        ```

        Maybe I'm just dumb, but I always thought "broken pipe" meant, "the other end of this socket closed before I finished sending something" and "connection reset by peer" meant, well, roughly the same thing. (As well as indicating some slightly more esoteric problems.)

        Turns out though, "broken pipe" actually means "I just tried to send something and the socket was already closed to sending."

        So in the following example, if the other end of (TCP) socket "sock" closes or dies before the write method, "connection reset by peer" will be raised. The next write will give a broken-pipe error, since the socket now knows that further sending is invalid.

        ```

        ```

        try:

            sock.write('foo')

        except:

            pass # connection reset by peer

        sock.write('bar') # broken pipe

        ```

       RST的标志位,这个标识为在如下几种情况下会被设置,以下是我了解的情况,可能还有更多的场景,没有验证:

        1. 当尝试和未开放的服务器端口建立tcp连接时,服务器tcp将会直接向客户端发送reset报文

        2. 双方之前已经正常建立了通信通道,也可能进行过了交互,当某一方在交互的过程中发生了异常,如崩溃等,异常的一方会向对端发送reset报文,通知对方将连接关闭

        3. 当收到TCP报文,但是发现该报文不是已建立的TCP连接列表可处理的,则其直接向对端发送reset报文

        4. ack报文丢失,并且超出一定的重传次数或时间后,会主动向对端发送reset报文释放该TCP连接

       å…¶å®žæˆ‘们java异常里看到的Broken pipe或者Connection reset by peer信息不是jdk或者jvm里定义的,我看到这些关键字往往会首先搜索下jdk或者hotspot源码找到位置进行上下文分析,但是没找到,后面才想到应该是Linux或者glibc里定义的,果然在glibc里看到了如上的描述和定义。

        对于Broken pipe在管道的另外一端没有进程在读的时候就会抛出此异常,Connection reset by peer的描述其实不是很正确,从我的实践来看只描述了一方面,其实在某一端正常close之后,也是可能会有此异常的。

       connection reset by peer”和”broken pipe”出现的场景:

        1)往一个对端已经close的通道写数据的时候,对方的tcp会收到这个报文,并且反馈一个reset报文。当收到reset报文的时候,继续做select读数据的时候就会抛出Connect reset by peer的异常,。

        2)当第一次往一个对端已经close的通道写数据的时候会和上面的情况一样,会收到reset报文。当再次往这个socket写数据的时候,就会抛出Broken pipe了 。根据tcp的约定,当收到reset包的时候,上层必须要做出处理,调用将socket文件描述符进行关闭,其实也意味着pipe会关闭,因此会抛出这个顾名思义的异常。

       ä»Žtcp原理角度理解Broken pipe和Connection Reset by Peer的区别

       /blog////tcp-broken-pipe

       å…³äºŽtcp socket出现的”connection reset by peer“和“broken pipe”

       ////%E5%%B3%E4%BA%8Etcp-socket%E5%%BA%E7%8E%B0%E7%9A%connection-reset-by-peer%E5%%8Cbroken-pipe

liux c socket编程,在main返回后出现 stack smash detected

       å¦‚果收到个字符

       é‚£ä¹ˆ recvbuff[recvbytes] = '\0';

       è¿™å¥å°±å†™è¶Šç•Œäº†

       åº”该改为

       <code>

        // MAXSIZE 改为 MAXSIZE -1

        if((recvbytes=recv(sockfd,recvbuff,MAXSIZE-1,0))==-1)

        {

        perror("recv 接受数据出错");

        exit(2);

        }

       </code>