在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux內(nèi)核中的文件描述符(二)--socket和文件描述符

            linux內(nèi)核中的文件描述符(二)--socket和文件描述符

            作者: 時(shí)間:2016-11-22 來(lái)源:網(wǎng)絡(luò) 收藏
            Kernel version:2.6.14

            CPU architecture:ARM920T

            本文引用地址:http://www.biyoush.com/article/201611/319998.htm

            Author:ce123(http://blog.csdn.net/ce123)

            socket和文件系統(tǒng)緊密相關(guān),我們可以通過(guò)文件系統(tǒng)的open、read、write和close等操作socket。下面是一個(gè)簡(jiǎn)單的例子。

            [plain]view plaincopy
            print?
            1. /****************************************************************************/
            2. /*簡(jiǎn)介:TCPServer示例*/
            3. /****************************************************************************/
            4. #include
            5. #include
            6. #include
            7. #include
            8. #include
            9. #include
            10. #include
            11. #include
            12. intmain(intargc,char*argv[])
            13. {
            14. intsockfd,new_fd;
            15. structsockaddr_inserver_addr;
            16. structsockaddr_inclient_addr;
            17. intsin_size,portnumber;
            18. constcharhello[]="Hellon";
            19. if(argc!=2)
            20. {
            21. fprintf(stderr,"Usage:%sportnumberan",argv[0]);
            22. exit(1);
            23. }
            24. if((portnumber=atoi(argv[1]))<0)
            25. {
            26. fprintf(stderr,"Usage:%sportnumberan",argv[0]);
            27. exit(1);
            28. }
            29. /*服務(wù)器端開始建立socket描述符*/
            30. if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
            31. {
            32. fprintf(stderr,"Socketerror:%sna",strerror(errno));
            33. exit(1);
            34. }
            35. /*服務(wù)器端填充sockaddr結(jié)構(gòu)*/
            36. bzero(&server_addr,sizeof(structsockaddr_in));
            37. server_addr.sin_family=AF_INET;
            38. server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
            39. server_addr.sin_port=htons(portnumber);
            40. /*捆綁sockfd描述符*/
            41. if(bind(sockfd,(structsockaddr*)(&server_addr),sizeof(structsockaddr))==
            42. -1)
            43. {
            44. fprintf(stderr,"Binderror:%sna",strerror(errno));
            45. exit(1);
            46. }
            47. /*監(jiān)聽sockfd描述符*/
            48. if(listen(sockfd,5)==-1)
            49. {
            50. fprintf(stderr,"Listenerror:%sna",strerror(errno));
            51. exit(1);
            52. }
            53. while(1)
            54. {
            55. /*服務(wù)器阻塞,直到客戶程序建立連接*/
            56. sin_size=sizeof(structsockaddr_in);
            57. if((new_fd=accept(sockfd,(structsockaddr*)(&client_addr),&sin_size))==-1)
            58. {
            59. fprintf(stderr,"Accepterror:%sna",strerror(errno));
            60. exit(1);
            61. }
            62. fprintf(stderr,"Servergetconnectionfrom%sn",
            63. inet_ntoa(client_addr.sin_addr));
            64. if(write(new_fd,hello,strlen(hello))==-1)
            65. {
            66. fprintf(stderr,"WriteError:%sn",strerror(errno));
            67. exit(1);
            68. }
            69. /*這個(gè)通訊已經(jīng)結(jié)束*/
            70. close(new_fd);
            71. /*循環(huán)下一個(gè)*/
            72. }
            73. close(sockfd);
            74. exit(0);
            75. }

            下圖說(shuō)明了socket和fd是怎樣聯(lián)系起來(lái)的。

            下面通過(guò)來(lái)具體分析一下。sys_socket是socket相關(guān)函數(shù)的總?cè)肟凇?/p>

            [plain]view plaincopy
            print?
            1. net/socket.c
            2. /*
            3. *Systemcallvectors.
            4. *
            5. *Argumentcheckingcleanedup.Saved20%insize.
            6. *Thisfunctiondoesntneedtosetthekernellockbecause
            7. *itissetbythecallees.
            8. */
            9. asmlinkagelongsys_socketcall(intcall,unsignedlong__user*args)
            10. {
            11. unsignedlonga[6];
            12. unsignedlonga0,a1;
            13. interr;
            14. if(call<1||call>SYS_RECVMSG)
            15. return-EINVAL;
            16. /*copy_from_usershouldbeSMPsafe.*/
            17. if(copy_from_user(a,args,nargs[call]))
            18. return-EFAULT;
            19. err=audit_socketcall(nargs[call]/sizeof(unsignedlong),a);
            20. if(err)
            21. returnerr;
            22. a0=a[0];
            23. a1=a[1];
            24. switch(call)
            25. {
            26. caseSYS_SOCKET:
            27. err=sys_socket(a0,a1,a[2]);
            28. break;
            29. caseSYS_BIND:
            30. err=sys_bind(a0,(structsockaddr__user*)a1,a[2]);
            31. break;
            32. caseSYS_CONNECT:
            33. err=sys_connect(a0,(structsockaddr__user*)a1,a[2]);
            34. break;
            35. caseSYS_LISTEN:
            36. err=sys_listen(a0,a1);
            37. break;
            38. caseSYS_ACCEPT:
            39. err=sys_accept(a0,(structsockaddr__user*)a1,(int__user*)a[2]);
            40. break;
            41. caseSYS_GETSOCKNAME:
            42. err=sys_getsockname(a0,(structsockaddr__user*)a1,(int__user*)a[2]);
            43. break;
            44. caseSYS_GETPEERNAME:
            45. err=sys_getpeername(a0,(structsockaddr__user*)a1,(int__user*)a[2]);
            46. break;
            47. caseSYS_SOCKETPAIR:
            48. err=sys_socketpair(a0,a1,a[2],(int__user*)a[3]);
            49. break;
            50. caseSYS_SEND:
            51. err=sys_send(a0,(void__user*)a1,a[2],a[3]);
            52. break;
            53. caseSYS_SENDTO:
            54. err=sys_sendto(a0,(void__user*)a1,a[2],a[3],
            55. (structsockaddr__user*)a[4],a[5]);
            56. break;
            57. caseSYS_RECV:
            58. err=sys_recv(a0,(void__user*)a1,a[2],a[3]);
            59. break;
            60. caseSYS_RECVFROM:
            61. err=sys_recvfrom(a0,(void__user*)a1,a[2],a[3],
            62. (structsockaddr__user*)a[4],(int__user*)a[5]);
            63. break;
            64. caseSYS_SHUTDOWN:
            65. err=sys_shutdown(a0,a1);
            66. break;
            67. caseSYS_SETSOCKOPT:
            68. err=sys_setsockopt(a0,a1,a[2],(char__user*)a[3],a[4]);
            69. break;
            70. caseSYS_GETSOCKOPT:
            71. err=sys_getsockopt(a0,a1,a[2],(char__user*)a[3],(int__user*)a[4]);
            72. break;
            73. caseSYS_SENDMSG:
            74. err=sys_sendmsg(a0,(structmsghdr__user*)a1,a[2]);
            75. break;
            76. caseSYS_RECVMSG:
            77. err=sys_recvmsg(a0,(structmsghdr__user*)a1,a[2]);
            78. break;
            79. default:
            80. err=-EINVAL;
            81. break;
            82. }
            83. returnerr;
            84. }/*Itmaybealreadyanotherdescriptor8)Notkernelproblem.*/
            85. returnretval;
            86. out_release:
            87. sock_release(sock);
            88. returnretval;
            89. }
            當(dāng)應(yīng)用程序使用socket()創(chuàng)建一個(gè)socket時(shí),會(huì)執(zhí)行sys_socket,其定義如下

            [plain]view plaincopy
            print?
            1. asmlinkagelongsys_socket(intfamily,inttype,intprotocol)
            2. {
            3. intretval;
            4. structsocket*sock;
            5. retval=sock_create(family,type,protocol,&sock);//創(chuàng)建socket
            6. if(retval<0)
            7. gotoout;
            8. retval=sock_map_fd(sock);//分配一個(gè)未使用的文件描述符fd,并將socket和fd建立聯(lián)系
            9. if(retval<0)
            10. gotoout_release;
            11. out:
            12. /*Itmaybealreadyanotherdescriptor8)Notkernelproblem.*/
            13. returnretval;
            14. out_release:
            15. sock_release(sock);
            16. returnretval;
            17. }
            結(jié)構(gòu)體socket的定義如下(includelinuxnet.h):

            [plain]view plaincopy
            print?
            1. structsocket{
            2. socket_statestate;
            3. unsignedlongflags;
            4. structproto_ops*ops;
            5. structfasync_struct*fasync_list;
            6. structfile*file;//通過(guò)這個(gè)和文件描述符建立聯(lián)系
            7. structsock*sk;
            8. wait_queue_head_twait;
            9. shorttype;
            10. };
            下面我們?cè)賮?lái)看看sock_map_fd函數(shù)

            [plain]view plaincopy
            print?
            1. intsock_map_fd(structsocket*sock)
            2. {
            3. intfd;
            4. structqstrthis;
            5. charname[32];
            6. /*
            7. *Findafiledescriptorsuitableforreturntotheuser.
            8. */
            9. fd=get_unused_fd();//分配一個(gè)未使用的fd
            10. if(fd>=0){
            11. structfile*file=get_empty_filp();
            12. if(!file){
            13. put_unused_fd(fd);
            14. fd=-ENFILE;
            15. gotoout;
            16. }
            17. this.len=sprintf(name,"[%lu]",SOCK_INODE(sock)->i_ino);
            18. this.name=name;
            19. this.hash=SOCK_INODE(sock)->i_ino;
            20. file->f_dentry=d_alloc(sock_mnt->mnt_sb->s_root,&this);
            21. if(!file->f_dentry){
            22. put_filp(file);
            23. put_unused_fd(fd);
            24. fd=-ENOMEM;
            25. gotoout;
            26. }
            27. file->f_dentry->d_op=&sockfs_dentry_operations;
            28. d_add(file->f_dentry,SOCK_INODE(sock));
            29. file->f_vfsmnt=mntget(sock_mnt);
            30. file->f_mapping=file->f_dentry->d_inode->i_mapping;
            31. sock->file=file;//建立聯(lián)系
            32. file->f_op=SOCK_INODE(sock)->i_fop=&socket_file_ops;//socket操作函數(shù),當(dāng)使用文件系統(tǒng)的IO函數(shù)時(shí),其實(shí)使用的是socket的IO函數(shù)
            33. file->f_mode=FMODE_READ|FMODE_WRITE;
            34. file->f_flags=O_RDWR;
            35. file->f_pos=0;
            36. file->private_data=sock;
            37. fd_install(fd,file);
            38. }
            39. out:
            40. returnfd;
            41. }
            42. staticstructfile_operationssocket_file_ops={
            43. .owner=THIS_MODULE,
            44. .llseek=no_llseek,
            45. .aio_read=sock_aio_read,
            46. .aio_write=sock_aio_write,
            47. .poll=sock_poll,
            48. .unlocked_ioctl=sock_ioctl,
            49. .mmap=sock_mmap,
            50. .open=sock_no_open,/*specialopencodetodisallowopenvia/proc*/
            51. .release=sock_close,
            52. .fasync=sock_fasync,
            53. .readv=sock_readv,
            54. .writev=sock_writev,
            55. .sendpage=sock_sendpage
            56. };



            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉