linux内核中的文件描述符(二)--socket和文件描述符
时间:11-22
来源:互联网
点击:
Kernel version:2.6.14
CPU architecture:ARM920T
Author:ce123(http://blog.csdn.net/ce123)
socket和文件系统紧密相关,我们可以通过文件系统的open、read、write和close等操作socket。下面是一个简单的例子。
[plain]view plaincopyprint?
- /****************************************************************************/
- /*简介:TCPServer示例*/
- /****************************************************************************/
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- intmain(intargc,char*argv[])
- {
- intsockfd,new_fd;
- structsockaddr_inserver_addr;
- structsockaddr_inclient_addr;
- intsin_size,portnumber;
- constcharhello[]="Hello\n";
- if(argc!=2)
- {
- fprintf(stderr,"Usage:%sportnumber\a\n",argv[0]);
- exit(1);
- }
- if((portnumber=atoi(argv[1]))<0)
- {
- fprintf(stderr,"Usage:%sportnumber\a\n",argv[0]);
- exit(1);
- }
- /*服务器端开始建立socket描述符*/
- if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
- {
- fprintf(stderr,"Socketerror:%s\n\a",strerror(errno));
- exit(1);
- }
- /*服务器端填充sockaddr结构*/
- bzero(&server_addr,sizeof(structsockaddr_in));
- server_addr.sin_family=AF_INET;
- server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
- server_addr.sin_port=htons(portnumber);
- /*捆绑sockfd描述符*/
- if(bind(sockfd,(structsockaddr*)(&server_addr),sizeof(structsockaddr))==
- -1)
- {
- fprintf(stderr,"Binderror:%s\n\a",strerror(errno));
- exit(1);
- }
- /*监听sockfd描述符*/
- if(listen(sockfd,5)==-1)
- {
- fprintf(stderr,"Listenerror:%s\n\a",strerror(errno));
- exit(1);
- }
- while(1)
- {
- /*服务器阻塞,直到客户程序建立连接*/
- sin_size=sizeof(structsockaddr_in);
- if((new_fd=accept(sockfd,(structsockaddr*)(&client_addr),&sin_size))==-1)
- {
- fprintf(stderr,"Accepterror:%s\n\a",strerror(errno));
- exit(1);
- }
- fprintf(stderr,"Servergetconnectionfrom%s\n",
- inet_ntoa(client_addr.sin_addr));
- if(write(new_fd,hello,strlen(hello))==-1)
- {
- fprintf(stderr,"WriteError:%s\n",strerror(errno));
- exit(1);
- }
- /*这个通讯已经结束*/
- close(new_fd);
- /*循环下一个*/
- }
- close(sockfd);
- exit(0);
- }
下图说明了socket和fd是怎样联系起来的。

下面通过来具体分析一下。sys_socket是socket相关函数的总入口。
[plain]view plaincopyprint?
- net/socket.c
- /*
- *Systemcallvectors.
- *
- *Argumentcheckingcleanedup.Saved20%insize.
- *Thisfunctiondoesntneedtosetthekernellockbecause
- *itissetbythecallees.
- */
- asmlinkagelongsys_socketcall(intcall,unsignedlong__user*args)
- {
- unsignedlonga[6];
- unsignedlonga0,a1;
- interr;
- if(call<1||call>SYS_RECVMSG)
- return-EINVAL;
- /*copy_from_usershouldbeSMPsafe.*/
- if(copy_from_user(a,args,nargs[call]))
- return-EFAULT;
- err=audit_socketcall(nargs[call]/sizeof(unsignedlong),a);
- if(err)
- returnerr;
- a0=a[0];
- a1=a[1];
- switch(call)
- {
- caseSYS_SOCKET:
- err=sys_socket(a0,a1,a[2]);
- break;
- caseSYS_BIND:
- err=sys_bind(a0,(structsockaddr__user*)a1,a[2]);
- break;
- caseSYS_CONNECT:
- err=sys_connect(a0,(structsockaddr__user*)a1,a[2]);
- break;
- caseSYS_LISTEN:
- err=sys_listen(a0,a1);
- break;
- caseSYS_ACCEPT:
- err=sys_accept(a0,(structsockaddr__user*)a1,(int__user*)a[2]);
- break;
- caseSYS_GETSOCKNAME:
- err=sys_getsockname(a0,(structsockaddr__user*)a1,(int__user*)a[2]);
- break;
- caseSYS_GETPEERNAME:
- err=sys_getpeername(a0,(structsockaddr__user*)a1,(int__user*)a[2]);
- break;
- caseSYS_SOCKETPAIR:
- err=sys_socketpair(a0,a1,a[2],(int__user*)a[3]);
- break;
- caseSYS_SEND:
- err=sys_send(a0,(void__user*)a1,a[2],a[3]);
- break;
- caseSYS_SENDTO:
- err=sys_sendto(a0,(void__user*)a1,a[2],a[3],
- (structsockaddr__user*)a[4],a[5]);
- break;
- caseSYS_RECV:
- err=sys_recv(a0,(void__user*)a1,a[2],a[3]);
- break;
- caseSYS_RECVFROM:
- err=sys_recvfrom(a0,(void__user*)a1,a[2],a[3],
- (structsockaddr__user*)a[4],(int__user*)a[5]);
- break;
- caseSYS_SHUTDOWN:
- err=sys_shutdown(a0,a1);
- break;
- caseSYS_SETSOCKOPT:
- err=sys_setsockopt(a0,a1,a[2],(char__user*)a[3],a[4]);
- break;
- caseSYS_GETSOCKOPT:
- err=sys_getsockopt(a0,a1,a[2],(char__user*)a[3],(int__user*)a[4]);
- break;
- caseSYS_SENDMSG:
- err=sys_sen
linux内核文件描述符socke 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
