套接字Socket:API

来源:互联网 发布:搜狐2016出品的网络剧 编辑:程序博客网 时间:2024/06/05 20:49

套接字
1、 套接字(socket)是一种通信机制,凭借这种机制,客户/服务器系统的开发工作既可以在本地单机上进行,也可以跨网络进行。Linux所提供的功能和网络工具通常都是用套接字来进行通信的。
2、 套接字应用程序是如何通过套接字来维持一个连接的:
1) 服务器应用程序用系统调用socket来创建一个套接字,它是系统分配给该服务器进行的类似文件描述符的资源,它不能与其他进程共享。
2) 服务器进程会给套接字起个名字。本地套接字的名字是Linux文件系统中的文件名,一般放在/tmp或/usr/tmp目录中。对于网络套接字,它的名字是与客户连接的特定网络有关的服务标识符。这个标志符允许Linux将进入的针对特定端口号的连接转到正确的服务器进程
3) 函数socket:创建一个socket通信。
表头文件:

        #include <sys/types.h>        #include <sys/socket.h>

函数定义:

int socket(int domain , int type , int protocol);
   函数说明:

1. socket() 用来建立一个新的socket,也就是向系统注册,通知系统建立一个通信端口。
2. 参数domain指定使用何种地址类型,完整的定义在/usr/include/bits/socket.h内:

*PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL:     UNIX进程通信协议;*PF_INET/AF_INET:       IPv4网络协议死;*PF_INET6/AF_INET6:     IPv6网络协议;*PF_IPX/AF_IPX:     IPX-Novell协议;*PF_NETLINK/AF_NETLINK:     核心用户接口装置;*PF_X25/AF_X25:     ITU- T X.25/ISO-8280协议;*PF_AX25/AF_AX25:       业余无线AX.25协议;*PF_ATMPVC/AF_ATMPVC:       存取原始ATM PVC;*PF_APPLETALK/AF_APPLETALK:     appletalk(DDP)协议;*PF_PACKET/AF_PACKET:       初级封包接口。
  1. 参数type有下列几种取值:
*SOCK_STREAM:提供双相连续且可信赖的数据流,即TCP,支持OOB机制,在所有数据传送前必须使用connect()来建立连线状态;    *SOCK_DGRAM:使用不连续不可信赖的数据包连接;    *SOCK_SEQPACKET:提供连续可信赖的数据包连接;    *SOCK_RAW:提供原始网络协议存取;    *SOCK_RDM:提供可信赖的数据包连接;    *SOCK_PACKET:提供和网络驱动程序直接通信。
  1. 参数protocol用来指定Socket所使用的传输协议编号,通常此参考不需要管他,设置为0即可。
    返回值:成功返回socket处理代码,失败返回-1。

4) 函数bind:用于对socket定位。
表头文件:

        #include <sys/types.h>        #include <sys/socket.h>

函数定义:

int bind(int sockfd , struct sockaddr * my_addr , int addrlen);

函数说明:
1. bind ()用来设置给参数sockfd的socket一个名称。此名称由参数my_addr指向sockaddr结构,对于不同的socket domain 定义了一个通用的结构体:

struct sockaddr{        unsigned short int sa_family;        char sa_data[14];};

sa_family:调用socket是的domain参数,即:AF_xxx;
sa_data[14]: 最多使用14个字符长度。

struct sockaddr_in{        unsigned short int sin_family;        uint16_t sin_port;        struct in_addr sin_addr;        unsigned char sin_zero[8];};struct in_addr{        Uint32_t s_addr;};

Sin_family: sa_family。
Sin_prot: 使用的port编号。
Sin_addr.s_addr: IP地址。
Sin_zero: 未使用。

参数addrlen为sockaddr的结构长度。
返回值:成功则返回0,失败返回-1,错误原因存在于errno中。

5) 函数listen:用于等待连接。
表头文件:

#include <sys/socket.h>

函数定义:

int listen(int s, int backlog);

函数说明:
listen()用来等待参数s的socket连线。参数backlog指向同时能处理的最大连接要求,如果连接数目达到此上限则client端将接收到ECONNREFUSED(econnrefused)的错误。listen()并未开始接收连线,只是设置socket为listen模式,真正接收client端连线的是accept()。通常listen()会在socket(),bind()之后调用,接着才调用accept()。
返回值:
成功则返回0,失败返回-1,错误原因存在于errno。
附加说明:
Listen()只适用于SOCK_STREAM或SOCK_SEQPACKET的socket类型。如果socket为AF_INET则参数backlog最大值可设至128。
错误代码:

EBADF: 参数socket非合法socket处理代码。EACCESS: 权限不足。EOPNOTSUPP: 指定的socket并未支援listen模式。

函数accept:用于接受socket连线。

6) 表头文件:

#include <sys/types.h>#include <sys/socket.h>

函数定义:

int accept (int s , struct sockaddr * addr , int * addrlen);

函数说明:
accept()用来接受参数s的socket连线。参数s的socket必须先经过bind()、listen()函数处理过,当有连线进来时accept()会返回一个新的socket处理代码,往后的数据传送与读取就由新的socket处理,而原来参数s的socket能继续使用accept()来接受新的连线要求。连线成功时,参数addr所指的结构会被系统填入远程主机的地址数据,参数addrlen为sockaddr的结构长度。
返回值:
成功则返回新的socket处理代码,失败返回-1,错误原因存在于errno中。
错误代码:

*EBADF: 参数s非合法socket处理代码;*EFAULT: 参数addr指针指向无法存取的内存空间;*ENOTSOCKET: 参数s为一文件描述词,非socket*EOPNOTSUPP: 指定的socket并非SOCK_STREAM;*EPERM: 防火墙拒绝此连线;*ENOBUFS: 系统的缓冲内存不够;*ENOMEM: 核心内存不够;

7) 函数connect: 用于建立socket连线。
表头文件:

#include <sys/types.h>#include <sys/socket.h>

函数定义:

int connect(int sockfd , struct sockaddr * serv_addr , int addrlen);

函数说明:
connect()用来将参数sockfd的socket连至参数serv_addr指定的网络地址。
参数addrlen为sockaddr的结构长度。
返回值:
成功返回0,失败返回-1,错误原因存在于errno中。
错误代码:

*EBADF: 参数sockfd非合法socket处理代码。*EFAULT: 参数serv_addr指针指向无法存取的内存空间。*ENOTSOCK: 参数sockfd为一文件描述词,非socket*EISCONN: 参数sockfd的socket已是连线状态。*ECONNERFUSED: 连线要求被server端拒绝。*ETIMEDOUT: 企图连线的操作超过限定时间仍未有响应。*ENETUNREACH: 无法传送数据包至指定的主机。*EAFNOSUPPORT: sockaddr结构的sa_family不正确。*EALREADY: socket为不可阻断且先前的连线操作还未完成。

8) 函数send:用于通过socket传送数据。
表头文件:

#include <sys/types.h>#include <sys/socket.h>

函数定义:

int send(int s , const void * msg , int len , unsigned int falgs);

函数说明:
send()用来将数据由指定的socket传给对方主机。参数s为已建立好连接的socket;参数msg指向欲连线的数据内容,参数len则为数据长度,参数flags一般设为0,其他数值定义如下:

*MSG_OOB: 传送的数据以out-of-band送出。*MSG_DONTROUTE: 取消路由表查询。*MSG_DONTWAIT: 设置为不可阻断运作。*MAG_NOSIGNAL: 此动作不愿被SIGPIPE信号中断。

返回值:
成功则返回实际传出去的字符数,失败返回-1.错误原因存于errno。
错误代码:

*EBADF: 参数s非合法的socket处理代码;*EFAULT: 参数中有一指针指向无法存取的内存空间;*ENOTSOCK: 参数s为一文件描述词,非socket*EINTR: 被信号所中断;*EAGAIN: 此操作会令进程阻断,但参数ssocket为不可阻断;*ENOBUFS: 系统缓冲内存不足;*ENOMEM: 核心内存不足;*EINVAL: 传给系统调用的参数不正确;

9) 函数sendto:用于通过socket传送数据。
表头文件

#include <sys/types.h>#include <sys/socket.h>

函数定义:

int sendto(int s , const void * msg , int len , unsigned int flags , const struct sockaddr * to , int tolen);

函数说明:
Sendto()用来将数据由指定的socket传给对方主机。参数s为已建好连线的socket,如果利用UDP协议则不需要经过连线操作;参数msg指向欲连线的数据内容;参数flags一般设为0,参数to用来指定欲传送的网络地址,参数tolen为sockaddr的结果长度。
返回值:
成功则返回实际传出去的字符数,失败返回-1,错误原因存于errno中。
错误代码:

*EBADF: 参数s非法的socket处理代码;*EFAULT: 参数中有一指针指向无法存取的内存空间;*WNOTSOCK: 参数s为一文件描述词;*EINTR: 被信号所中断;*EAGAIN: 此动作会令进程阻断,但参数ssocket是不可阻断的;*ENOBUFS: 系统的缓冲内存不够;*EINVAL: 传给系统调用的参数不正确;

10) 函数recv:用于通过socket接受数据。
表头文件:

#include <sys/types.h>#include <sys/socket.h>

函数定义:

int recv(int s , void * buf , int len , unsigned int flags);

返回值:
成功返回实际传送出去的字符数,失败则返回-1。错误原因存于errno。
错误代码:

*EBADF: 参数s非合法的socket处理代码;*EFAULT: 参数中有一指针指向无法存取的内存空间;*ENOTSOCK: 参数s为一文件描述词,非socket*EINTR: 被信号所中断;*EAGAIN: 此操作会令进程阻断,但参数ssocket为不可阻断;*ENOBUFS: 系统缓冲内存不够;*ENOMEM: 核心内存不够;*EINVAL: 传给系统调用的参数不正确;

11) 函数recvfrom:通过socket接受数据。
表头文件:

#include <sys/types.h>#include <sys/socket.h>

函数定义:

int recvfrom(int s , void *buf , int len , unsigned int flags , struct sockaddr * from , int *fromlen);

函数说明:
recv()用来接收远程主机经指定的socket传来的数据,并把数据存到由参数buf指向的内存空间。参数len为可接收数据的最大长度;参数flags一般设0,参数from用来指定欲传送的网络地址,参数fromlen为sockaddr的结构长度。
返回值:
成功则返回收到的字符数,失败则返回-1,错误原因存于errno中。
错误代码:

*EBADF: 参数s非合法的socket处理代码;*EFAULT: 参数中有一指针指向无法存取的内存空间;*ENOTSOCK: 参数s为一文件描述词,非socket*EINTR: 被信号所中断;*EAGAIN: 此动作会令进程阻断,但参数ssocket为不可阻断;*ENOBUFS: 系统的缓冲内存不足;*ENOMEM: 核心内存不足;*EINVAL: 传给系统调用的参数不正确。
0 0
原创粉丝点击