Linux Socket学习--域和套接口简介
来源:互联网 发布:立体图设计软件绿色版 编辑:程序博客网 时间:2024/05/02 00:45
转:http://www.cnblogs.com/rollenholt/archive/2012/08/16/2641838.html
套接口创建后,就如同一个文件描述符,我们可以使用同样的IO函数进行读写,关闭操作。其实,和引用一个已经打开的文件一样,套接口也是通过文件描述符来引用的,而且两者的文件描述符共享一个“数字空间”,比如说不能既打开一个文件描述符为4的套接口,又打开一个文件描述符为4的文件。
套接口和已经打开的文件的区别:
1.不能在套接口上调用函数lseek()当然对于管道也不能调用这个函数。
2.套接口可以和网络地址关联,但是文件和管道却不可以。
3.套接口有很多可以通过ioctl()进行查询和设置的选项。
4.套接口必须在正确的状态写才能进行输入输出,但是已经打开的文件可以在任何的时候进行读写操作。
调用open()函数打开一个新文件,Linux内核会返回一个当前系统可用的最小的文件描述符。比如如果关闭了标准输入(文件描述符0),又立即打开一个新文件,那么新文件的文件描述符就是0.
另外要注意的是Linux内核在分配文件描述符的时候,并不区分这个描述符是分配给套接口还是给已经打开的文件的。
我们知道,使用int pipe(int fileds[2]);函数可以创建管道,如果这个函数调用成功,内核会返回两个文件描述符,fileds[0]表示管道读出端的文件描述符,fileds[1]表示管道写入端的文件描述符。所以可以看出管道是单向的,任何的反方向操作会导致错误。
但是套接口不同,他可以进行双向通信。这个也是他和管道的根本差异。
创建一个套接口使用以下的函数:
#include <sys/types.h>#include <sys/socket.h>int socketpair(int domain,int type,int protocol,int sv[2]);
下面我们来展示一个socketpair的例子:
#include <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>int main(int argc, char const *argv[]){ int state; int s[2]; state=socketpair(AF_LOCAL,SOCK_STREAM,0,s); if (state== -1) { fprintf(stderr, "an error %s has happend.\n", strerror(errno); return 1; } printf("s[0]=%d\n", s[0]); printf("s[1]=%d\n", s[1]); return 0;}
其中AF_LOCAL套接口又被称为是unix套接口,所以使用AF_UNIX和使用AF_LOCAL都是一样的。不过建议使用AF_LOCAL。
下面我们来展示一下使用套接口实现I/O
………………UNDONE(此处代码待添加)
我们来看看如何关闭套接口
当我们从管道读取输入的时候,读取进程受到文件结束标识以后就知道没有后续文件了,因为文件描述符是由写进程关闭管道的写段的时候发送的。套接口的关闭类似,当在套接口发送端关闭后,接受端就会受到文件结束标识,但是这种关闭方式不适用所有的情况。close终止了数据传送的两个方向:读和写,由于TCP是全双工的,在很多的情况下,本地进程要通知远程端点已经完成了数据的发送工作,但是仍然等待从远程端点接受数据,在这种情况下,我们需要对套接口进行半关闭操作,就需要用到shutdown函数:
#include <sys/socket.h>int shutdown(int s, int how);
其中s是需要进行半关闭的套接口,需要进行关闭的方式是how,参数how的取值请看下表:
值宏描述0SHUT_RD进程不能对指定套接口进行读操作1SHUT_WR进行不能对指定套接口进行写操作2SHUT_RDWR进程不能对指定套接口进行读写操作大家可以看出,当how参数的取值为2的时候,shutdown函数和close函数一样了。下面举一个例子:
int state;int s;state=shutdown(s,SHUT_WR);if(z == -1){perror("shundown...");}
下面我们来看看如何处理复制套接口的情况:
如果调用函数dup或者dup2的话,那么只有最后一个close调用才可以关闭套接口,系统这样做,是因为他认为其他复制的文件描述符仍然在使用中,如下所示:
int s; //已经存在的套接口
int d; //被复制的套接口
d=dup(s); //复制套接口
close(s) // 套接口并未被关闭
close(d) //套接口被关闭
在上面的例子中,第一个close函数调用并没有关闭套接口,其实无论先关闭s还是先关闭d,没任何区别。而只有当最后一个文件描述符被关闭的时候,套接口才是被真正的关闭了。但是如果使用shutdown函数的话,就没有这个问题。:
int s
int d;
d=dup(s);
shutdown(s,SHUT_RDWR);
即使套接口s仍然通过文件描述符d打开,shutdown函数仍然立即将套接口彻底关闭。
建议:总是使用shutdown函数来代替close函数。
当调用shutdown函数的时候,如果给定的套接口不是有效的文件描述符,返回EBADF错误。
如果给定的文件描述符不是套接口,返回ENOTSOCK错误
如果套接口出于非连接状态,返回ENOTCONN错误。
注意:即便是使用参数为SHUT_RDWR的时候,函数shutdown也不会释放文件描述符,在使用close释放文件描述符之前,他一直可用。
- Linux Socket学习--域和套接口简介
- Linux Socket学习之:套接口选项 getsockopt 、setsockopt
- 学习笔记《实战Linux Socket编程》第五章 为套接口绑定地址
- 1. 套接口简介
- 套接口编程简介
- 原始套接口(RAW SOCKET)
- socket套接口函数详解
- TCP套接口编程(Socket)
- linux 套接口缓存
- UNIX的套接口(Socket)编程简介 (http://www.fanqiang.com)
- 【Linux】正确使用SO_RCVTIMEO和SO_SNDTIMEO套接口选项
- 网络编程学习笔记(ICMPv6和IPv6套接口选项)
- UDP socket (UDP套接口通信)
- c语言socket套接口API
- 套接口Socket数据发送过程详解
- unix下socket套接口编程详解
- UNIX的套接口(Socket)编程
- socket套接口选项设置实例
- Servelet线程安全问题。
- Linux管道PIPE的原理和应用
- Real-Time Rendering-第四章 Transforms
- lightoj Beginners Problems(求面积)
- label 标签
- Linux Socket学习--域和套接口简介
- Uncaught RangeError: Maximum call stack size exceeded
- 最详细的VI编辑器指南
- |洛谷|BFS|P1141 01迷宫
- HDU2014
- 开始学习scala
- light oj(简化复杂度)
- Java基础Day06课后考试
- 自己总结的写安卓开发的点!!第一弹 shape~~~