因为不清楚 MSG_PEEK 是否阻塞所以写代码测试。
结论:recv falg 为 MSG_PEEK 时候是阻塞的。
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#define ANET_OK 0
#define ANET_ERR -1
#define ANET_ERR_LEN 256
#define ANET_CONNECT_NONE 0
#define ANET_CONNECT_NONBLOCK 1
static void anetSetError(char *err, const char *fmt, ...)
{
va_list ap;
if (!err) return;
va_start(ap, fmt);
vsnprintf(err, ANET_ERR_LEN, fmt, ap);
va_end(ap);
}
static int anetTcpGenericConnect(char *err, char *addr, int port, int flags)
{
int s, on = 1;
struct sockaddr_in sa;
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
anetSetError(err, "creating socket: %s\n", strerror(errno));
return -1;
}
/* Make sure connection-intensive things like the redis benckmark
* * will be able to close/open sockets a zillion of times */
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
if (inet_aton(addr, &sa.sin_addr) == 0) {
struct hostent *he;
he = gethostbyname(addr);
if (he == NULL) {
anetSetError(err, "can't resolve: %s\n", addr);
close(s);
return -1;
}
memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr));
}
if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
if (errno == EINPROGRESS &&
(flags & ANET_CONNECT_NONBLOCK) )
return s;
close(s);
return -1;
}
return s;
}
int main()
{
char err[1000] = { 0 };
int fd = anetTcpGenericConnect( err, "127.0.0.1", 8080, ANET_CONNECT_NONBLOCK );
if( fd < 0 )
{
printf( "err=%s\n", err );
return -1;
}
char buf[100] = {0};
int recvByte = recv( fd, buf, 100, MSG_PEEK );
printf( "recvByte=%d,buf=%s\n", recvByte, buf );
return 0;
}