分类: C/C++
2010-03-05 19:29:33
recv,recvfrom,recvmsg函数用于从套接字接收信息。
ssize_t recv (int s, void *buf, size_t len, int flags);
ssize_t recvfrom (int s, void * restrict buf, size_t len, int flags,
struct sockaddr * restrict from, socklen_t * restrict fromlen);
ssize_t recvmsg (int s, struct msghdr *msg, int flags);
recvfrom和recvmsg系统调用用于从套接字接收消息,也可以用来接受套接字数据,不管其是否是面向连接的。 recv函数通常用于面向连接的套接字(参看[[[Open C 套接字: connect 方法|connect]]),等同于用空指针传入from参数时
的recvfrom。所有三个例程都返回成功时的消息长度。
recvmsg系统调用使用msghdr结构将直接提供的参数个数减到最少,这个结构具有以下格式,定义在sys/socket.h文件:
struct msghdr {
caddr_t msg_name; /* optional address */
u_int msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
u_int msg_iovlen; /* # elements in msg_iov */
caddr_t msg_control; /* ancillary data, see below */
u_int msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};
下面的代码片段演示了recv, recvfrom, recvmsg函数的用法:
#include
#include
#include
void Recv()
{
struct sockaddr_in serv_addr;
int sock_fd;
char line[10];
int size = 10;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
serv_addr.sin_port = htons(5000);
sock_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
connect(sock_fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
recv(sock_fd, line, size, 0);
close(sock_fd);
}
#include
#include
#include
void Sendto()
{
struct sockaddr_in sender_addr;
int sock_fd;
char line[15] = "Hello World!";
unsigned int size = sizeof(sender_addr);
sock_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
sender_addr.sin_family = AF_INET;
sender_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sender_addr.sin_port = htons(5000);
recvfrom(sock_fd,line,13,0,(struct sockaddr*)&sender_addr,&size);
close(sock_fd);
}
#include
#include
#include
void SendMsgRecvMsg()
{
int sock_fd;
unsigned int sender_len;
struct msghdr msg;
struct iovec iov;
struct sockaddr_in receiver_addr,sender_addr;
char line[10];
sock_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
receiver_addr.sin_family = AF_INET;
receiver_addr.sin_addr.s_addr = htonl(INADDR_ANY);
receiver_addr.sin_port = htons(5000);
bind(sock_fd,(struct sockaddr*)&receiver_addr,sizeof(receiver_addr));
sender_len = sizeof(sender_addr);
msg.msg_name = &sender_addr;
msg.msg_namelen = sender_len;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_iov->iov_base = line;
msg.msg_iov->iov_len = 10;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
recvmsg(sock_fd,&msg,0);
close(sock_fd);
}
这些调用返回接收的字节数,或者如错误发生返回-1。
==========================================================================================