常用socket函数

来源:互联网 发布:韶关市新丰县网络问政 编辑:程序博客网 时间:2024/05/16 09:57

常用socket函数详解

主要介绍:socket、connect、bind、listen、accept、send、sendto、recv、recvfrom、close、shutdown

其在linux和windows环境下的头文件主要是:#include<sys/socket.h>#include<WinSock2.h>

socket -> bind -> listen ->accpet

1.  socket

int socket(int family, int type, int protocol)
返回:非负描述字──成功, -1──出错

参数:
family :这个参数指定一个协议簇,也往往被称为协议域。系统存在许多可以的协议簇,常见有AF_INET──IPv4,AF_INET6──IPv6,AF_LOCAL──UNIX 协议域等等。它值都是系统预先定义的宏,系统支持哪些协议我们才可以使用,否则会调用失败。协议簇是网络层的协议。 可以到内核源码linux/socket.h中查看支持的协议簇有哪些。 另外有#define PF_* AF_*

type :这个参数指定一个套接口的类型:SOCK_STREAM、SOCK_DGRAM、SOCK_SEQPACKET、SOCK_RAW等等,它们分别表明字节流、数据报、有序分组、原始套接口。需要注意的,并不是每一种协议簇都支持这里的所有的类型,所以类型与协议簇要匹配。 

protocol :指定相应的传输协议,也就是诸如TCP或UDP协议等等,系统针对每一个协议簇与类型提供了一个默认的协议,我们通过把protocol设置为0来使用这个默认的值。
一般取为0。成功时,返回一个小的非负整数值,与文件描述符类似。

返回值:socket函数返回一个套接字,即套接口描述字。如果出现错误,它返回-1。


2.  connect

int connect(int sockfd, conststruct sockaddr *addr, socklen_t addrlen)

函数说明:通过此函数建立于TCP服务器的连接,实际是发起三次握手过程,仅在连接成功或失败后返回。connect函数通常用于客户端建立tcp连接。

参数:
sockfd:标识一个套接字。
serv_addr:套接字s想要连接的主机地址和端口号。
addrlen:name缓冲区的长度。

返回值:
成功则返回0,失败返回-1,错误原因存于errno中。

UDP的connect函数,结果与tcp调用不相同,没有三次握手过程。内核只是记录对方的ip和端口号,他们包含在传递给connect的套接口地址结构中,并立即返回给调用进程。


3.  bind

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

函数说明:bind()用来设置给参数sockfd 的socket 一个名称. 此名称由参数my_addr 指向一sockaddr 结构,对于不同的socket domain 定义了一个通用的数据结构
struct sockaddr
{
   unsigned short int sa_family;
   char sa_data[14];
};
1、sa_family 为调用socket()时的domain 参数, 即AF_xxxx 值.
2、sa_data 最多使用14 个字符长度.

此sockaddr 结构会因使用不同的socket domain 而有不同结构定义, 例如使用AF_INET domain,其socketaddr 结构定义便为
struct socketaddr_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;
};
1、sin_family 即为sa_family
2、sin_port 为使用的port 编号
3、sin_addr. s_addr 为IP 地址 sin_zero 未使用.
参数 addrlen 为sockaddr 的结构长度.

返回值:成功则返回0, 失败返回-1, 错误原因存于errno 中.


4.  listen

int listen(int s, int backlog);

函数说明:listen()用来等待参数s 的socket 连线.

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


5.  accept

int accept(int s, struct sockaddr * addr, int * addrlen);
函数说明:accept()用来接受参数s 的socket 连线.

参数:

s 的socket 必需先经bind()、listen()函数处理过, 当有连线进来时accept()会返回一个新的socket 处理代码, 往后的数据传送与读取就是经由新的socket处理, 而原来参数s 的socket 能继续使用accept()来接受新的连线要求.

连线成功时, 参数addr 所指的结构会被系统填入远程主机的地址数据,

参数addrlen 为scokaddr 的结构长度. 关于机构sockaddr 的定义请参考bind().

返回值:成功则返回新的socket 处理代码, 失败返回-1, 错误原因存于errno 中.


6.  send

int send(SOCKET s,  const char*buf,   int len,   int flags);

参数:

s        发送端套接字描述符

buf      应用程序要发送的数据的缓冲区(想要发送的数据)

len      实际要发送的字节数

flags   一般置为0即可


7.  recv

int recv( SOCKET s,     char FAR *buf,      int len,     int flags     );   

函数说明:不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。

参数:

s:指定接收端套接字描述符;

buf:指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;

len:指明buf的长度;

flags:一般置0。其他数值定义如下:
                   1、MSG_OOB 接收以out-of-band 送出的数据.
                   2、MSG_PEEK 返回来的数据并不会在系统内删除, 如果再调用recv()会返回相同的数据内容.
                   3、MSG_WAITALL 强迫接收到len 大小的数据后才能返回, 除非有错误或信号产生.
                   4、MSG_NOSIGNAL 此操作不愿被SIGPIPE 信号中断返回值成功则返回接收到的字符数, 失败返回-1,错误原因存于errno 中.

这里只描述同步Socket的recv函数的执行流程。当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR,如果s的发送缓冲中没有数 据或者数据被协议成功发送完毕后,recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数据,那么recv就一直等待,只到 协议把数据接收完毕。当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据copy到buf中(注意协议接收到的数据可能大于buf的长度,所以 在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的),recv函数返回其实际copy的字节数。如果recv在copy时出错,那么它返回SOCKET_ERROR;如果recv函数在等待协议接收数据时网络中断了,那么它返回0


0 0
原创粉丝点击