recv() 阻塞&非阻塞

server.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define MYPORT 8100 //连接时使用的端口
#define MAXCLINE 5 //连接队列中的个数
int conn_amount; //当前的连接数


int main(void)
{
	int sock_fd,new_fd; //监听套接字 连接套接字
	struct sockaddr_in server_addr; // 服务器的地址信息
	struct sockaddr_in client_addr; //客户端的地址信息
	socklen_t sin_size;
	int yes = 1;
	char buf[1024];
	int ret;
	int i;

	//建立sock_fd套接字
	if((sock_fd = socket(AF_INET,SOCK_STREAM,0))==-1)
	{
		perror("setsockopt");
		exit(1);
	}
	printf("sockect_fd = %d\n", sock_fd);

	server_addr.sin_family = AF_INET; //主机字节序
	server_addr.sin_port = htons(MYPORT);
	server_addr.sin_addr.s_addr = INADDR_ANY;//通配IP
	memset(server_addr.sin_zero,'\0',sizeof(server_addr.sin_zero));

	if(bind(sock_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) == -1)
	{
		perror("bind error!\n");
		exit(1);
	}
	if(listen(sock_fd,MAXCLINE)==-1)
	{
		perror("listen error!\n");
		exit(1);
	}
	printf("listen port %d\n",MYPORT);
    new_fd = accept(sock_fd,(struct sockaddr *)NULL, NULL);
    if(new_fd == -1){
        printf("accept socket error: %s\n",strerror(errno));
    }
    int count = 0;
int flag = 0;
//MSG_DONTROUTE 绕过路由表查找。
//MSG_DONTWAIT 仅本操作非阻塞。
//MSG_OOB 发送或接收带外数据。
//MSG_PEEK 窥看外来消息。
//MSG_WAITALL 等待所有数据。
	while(1)
    {
        printf("第 %d 次recv \n",++count);
        ret = recv(new_fd,buf,sizeof(buf),flag);
        if(ret > 0){
            printf("收到 %d Byte[%s] \n",ret,buf);
        }else if (ret < 0){
            if(ret == EAGAIN){
                printf("没有数据可读\n");
            }
        }else{
            printf("连接断开\n");
            break;
        }
        sleep(1);

    }
}

client.c
//客户端
#include <sys/types.h> 
#include <sys/socket.h> 
#include <stdio.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <unistd.h> 
#include <stdlib.h>
#include <sys/time.h>
#include <string.h>
#define SERVER_IP "192.192.255.63"
int main() 
{ 
	int client_sockfd; 
	int len; 
	struct sockaddr_in address;//服务器端网络地址结构体 
	int result; 
    int count = 0;
    char msg[16];
	client_sockfd = socket(AF_INET, SOCK_STREAM, 0);//建立客户端socket 
	address.sin_family = AF_INET; 
	//address.sin_addr.s_addr = inet_addr(SERVER_IP);
	address.sin_addr.s_addr =INADDR_ANY; 
	address.sin_port = htons(8100); 
	len = sizeof(address); 
	result = connect(client_sockfd, (struct sockaddr *)&address, len); 
	if(result == -1) 
	{ 
		perror("oops: client2"); 
		exit(1); 
	} 
    int flag = 0;
    while(1){
        memset(msg,0,sizeof(msg));
        sprintf(msg,"client-> send%d",count++);
        send(client_sockfd, msg, sizeof(msg),flag); 
        printf("client have send %s \n",msg);
        sleep(15);
    }
	close(client_sockfd); 

	return 0; 
}

1. recv 默认是阻塞还是非阻塞?

这里把client发送一次消息后(为了证明server能收到),sleep150s,如果recv一直轮训接收那就是非阻塞,如果一直等,那就是默认阻塞,这里recv flag = 0;

第一次收到后,一直阻塞,所以默认是阻塞的,即收不到消息一直等待;

2. 其他flag参数

2.1 MSG_DONTWAIT

修改server.c   - >  int flag = MSG_DONTWAIT;

这里的执行结果可以看到此时recv不是一直等待,而是返回进行了后续的recv操作;

 2.2 MSG_WAITALL

修改server.c   - >  int flag = MSG_WAITALL; char buf[24];

server.c 一次需要接收24 Byte,而client一次发送才14Byte,看recv如何表现

每次接收24 Byte(buf的size)才返回,即MSG_WAITALL使用的时候,把recv的buf填满才返回;

 

 

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打个工而已

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值