listen()函数
功能
用于面向连接服务器,表明愿意接收连接
#include <sys/socket.h>
函数原型
int listen(int s, int backlog);
参数说明
sockfd:调用socket返回的文件描述符
backlog:accept()应答之前,允许在进入队列中等待的连接数目,出错时返回-1
返回值
成功时,返回0
失败时,返回-1
说明
在使用listen()之前,需要调用bind()绑定到需要的端口,否则系统内核将会监听一个随机端口
accept()函数
功能
建立套接字连接,处理单个连接请求(如发送/接收数据)
#include <sys/socket.h>
函数原型
int accept(int sockfd, struct void*addr, socklen_t *addrlen);
参数说明
sockfd:正在监听端口的套接字文件描述符
addr:指向本地数据结构sockaddr_in的指针
调用connect()的信息将存储在该结构中
addrlen:设置为sizeof(struct sockaddr_in)
返回值
成功时,返回一个socket 端口
失败时,返回-1
int main() {
int sockfd, client_fd;
struct sockaddr_in remote_addr; /* 客户端地址信息 */
……
while(1) {
sin_size = sizeof(struct sockaddr_in);
if ((client_fd = accept(sockfd, (struct sockaddr *) &remote_addr, &sin_size)) == -1){
perror("accept"); continue;
}
printf("from %s\n", inet_ntoa(remote_addr.sin_addr));
……
}
……
}
send()函数
功能
通过socket发送数据
#include <sys/types.h>
#include <sys/socket.h>
函数原型
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
参数说明
sockfd:发送数据的套接字描述符
buf:指向发送数据的指针
len:数据长度
flags:一般设置为0
返回值
成功时,返回实际发送的数据的字节数
失败时,返回-1
recv()函数
功能
通过socket接收数据
#include <sys/types.h>
#include <sys/socket.h>
函数原型
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
参数说明
sockfd:要读的SOCKET描述符
buf:要读的信息的缓冲区
len:缓冲的最大长度
flags:一般设置为0
返回值
成功时,返回实际接收到的数据的字节数
失败时,返回-1
MSG_DONTROUTE
send()的使用标志,不查找路由表,表示目的主机在本地网络
MSG_OOB
接收或者发送带外数据
MSG_PEEK
recv()的使用标志,查看数据但不从系统缓冲区移走数据
MSG_WAITALL
recv()的使用标志,等待所有数据,阻塞式接收,直到满足条件或发生错误
读到指定字节时,正常返回,返回值等于len
读到文件尾,正常返回,返回值小于len
操作错误时,返回-1
带外数据
传输层协议使用带外数据(out-of-band, OOB)来发送一些重要数据
若通信一方有重要数据需要通知对方时,协议能将这些数据快速地发送到对方
为发送这些数据,协议一般不使用与普通数据相同的通道,而是使用另外的通道
Linux套接字机制支持低层协议发送/接收带外数据,但TCP协议没有真正意义上的带外数据
为发送重要协议,TCP提供紧急模式机制
TCP协议在数据段中设置URG位,表示进入紧急模式
接收方可以对紧急模式采取特殊的处理
这种方式数据不容易被阻塞,且可通过在服务器端程序里捕捉SIGURG信号来及时接收数据
TCP协议每次只能发送和接收一个字节带外数据
TCP发送带外数据的处理机制
TCP总将最后一个字节当作OOB数据,其余当作普通字节
不管通过带MSG_OOB标志的sendXXXX()函数发送多少字节OOB数据,发送端只将最后一个字节当作OOB数据
接收端也只能收到一个字节的OOB数据
举例:send(sendfd, “ABC”, 3, MSG_OOB)
TCP将紧急模式URG 置位
紧急指针定位第三个字节(“C”)
前两个字节(“AB”)当作普通字节发送
TCP提供两种处理模式
非OOBINLINE 模式:套接字的默认模式
将OOB字节与普通字节分开存放, OOB字节存放在一个OOB缓冲区中
OOBINLINE 模式:
OOB字节和普通字节一起存放
recvXXXX函数在MSG_OOB模式下,将在OOB缓冲区中寻找数据
如果发送端没发送OOB字节,它返回错误
如果发送端发送了OOB字节
对于非OOBINLINE 模式,返回1字节的OOB数据
对于OOBINLINE 模式,返回错误,因为OOB字节没有放到OOB缓冲区中
sendto()函数
功能
用于数据报套接字的通信
#include <sys/types.h>
#include <sys/socket.h>
函数原型
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
参数说明
to:目地机的IP地址和端口号信息
tolen:常被赋值为sizeof (struct sockaddr)
返回值
成功时,返回实际发送的数据的字节数
失败时,返回-1
recvfrom()函数
功能
用于数据报套接字的通信
#include <sys/types.h>
#include <sys/socket.h>
函数原型
int recvfrom(int sockfd,void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);
参数说明
from:保存源机的IP地址及端口号
fromlen:常常被赋值为sizeof (struct sockaddr)
返回值
成功时,返回实际接收到的数据的字节数
失败时,返回-1
write()函数
函数原型
ssize_t write(int fd, const void *buf, size_t nbytes)
功能
将buf中的nbytes字节内容写入文件描述符fd
返回值
成功时返回写的字节数
失败时返回-1,并设置errno变量
说明
返回值大于0,表示写入部分或全部数据
返回值小于0,表示出现错误
如果错误为EINTR ,表示在写的时候出现中断错误
如果为EPIPE,表示网络连接出现问题
read()函数
函数原型
ssize_t read(int fd, void *buf, size_t nbyte)
功能
从fd中读取内容
返回值
读成功时,返回实际所读的字节数
如果返回的值是0 表示已经读到文件的结束,
出错时,返回值小于0
如果错误为EINTR,说明读是由中断引起的
如果是ECONNREST表示网络连接出了问题
close()/shutdown()函数
功能
关闭通讯
函数原型
int close(int sockfd);
int shutdown(int sockfd, int how);
参数说明
sockfd:要关闭的套接字描述符
how:
0 :不允许接收
1 :不允许发送
2 :不允许发送和接收(和close() 一样)
返回值
成功时,返回0
失败时,返回-1
getpeername()/gethostname()函数
int getpeername(int sockfd, struct sockaddr* addr, int* addrlen);
获取socket连接另一端的主机信息
sockfd:是连接的数据流套接口文件描述符
addr:保存另一端主机信息
addrlen:设置为sizeof(struct sockaddr)
int gethostname(char *hostname, size_t size);
返回程序正在运行的计算机的名字
返回值
如果成功,返回0
如果失败,返回-1
IP地址与域名的获取
函数原型
#include <netdb.h>
struct hostent *gethostbyname(const char *name);
struct hostent *gethostbyaddr(const char *addr, size_t len, int type);
struct hostent{
char *h_name; /*主机的正式名称*/
char **h_aliases; /*主机的别名*/
int h_addrtype; /*主机的地址类型 AF_INET */
int h_length; /*主机的地址长度 对于IP4 是4字节32位*/
char **h_addr_list; /*主机的IP地址列表*/
#define h_addr h_addr_list[0] /*主机的第一个IP地址 */
};
时间: 2024-10-09 07:24:47