C语言socket客户端ipv6非阻塞模式收发

时间: 2023-07-25 12:20:01 浏览: 58
以下是一个简单的 C 语言 IPv6 Socket 客户端示例代码,使用非阻塞模式收发数据: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netdb.h> #include <sys/socket.h> #include <arpa/inet.h> #include <fcntl.h> #include <errno.h> #define PORT "8080" // 连接的端口号 #define MAXDATASIZE 100 // 接收缓冲区的大小 int main(int argc, char *argv[]) { int sockfd, numbytes, flags; struct addrinfo hints, *servinfo, *p; int rv; char s[INET6_ADDRSTRLEN]; char message[100]; // 发送的消息 char buf[MAXDATASIZE]; // 接收缓冲区 fd_set readfds, writefds; struct timeval tv; int retval; // 如果没有指定服务器的 IP 地址 if (argc != 2) { fprintf(stderr,"usage: client hostname\n"); exit(1); } memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // 遍历所有结果,直到成功连接为止 for (p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("client: socket"); continue; } if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("client: connect"); continue; } break; } if (p == NULL) { fprintf(stderr, "client: failed to connect\n"); return 2; } inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s); printf("client: connecting to %s\n", s); freeaddrinfo(servinfo); // 全部都用这个结构体 // 设置套接字为非阻塞模式 flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); // 发送消息 printf("Enter a message to send: "); fgets(message, 100, stdin); // 开始循环等待读写事件 while(1) { FD_ZERO(&readfds); FD_ZERO(&writefds); FD_SET(sockfd, &readfds); FD_SET(sockfd, &writefds); tv.tv_sec = 1; // 超时时间为 1 秒 tv.tv_usec = 0; retval = select(sockfd+1, &readfds, &writefds, NULL, &tv); if (retval == -1) { perror("select"); exit(1); } else if (retval == 0) { printf("Timeout occurred! No data after 1 seconds.\n"); continue; } else { // 有读写事件发生 if (FD_ISSET(sockfd, &writefds)) { int len = strlen(message); int bytes_sent = send(sockfd, message, len, 0); if (bytes_sent == -1) { perror("send"); exit(1); } printf("Sent %d bytes.\n", bytes_sent); } if (FD_ISSET(sockfd, &readfds)) { numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0); if (numbytes == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { perror("recv"); exit(1); } } else if (numbytes == 0) { printf("Connection closed by server.\n"); break; } else { buf[numbytes] = '\0'; printf("Received: %s\n", buf); } } } } close(sockfd); return 0; } ``` 需要注意的是,在使用非阻塞模式时,我们需要使用 `select` 函数来循环等待读写事件的发生。在上述代码中,我们设置超时时间为 1 秒,即如果在 1 秒内没有读写事件发生,就继续等待。 在 `select` 中,我们使用 `FD_SET` 函数将套接字加入到读写事件的集合中,并使用 `FD_ISSET` 函数来检查套接字是否就绪。如果套接字可写,我们就调用 `send` 函数发送消息;如果套接字可读,我们就调用 `recv` 函数接收数据。需要注意的是,`recv` 函数在非阻塞模式下可能会返回 -1,此时我们需要检查 `errno` 是否为 `EAGAIN` 或 `EWOULDBLOCK`,如果是,则说明当前没有数据可读,需要继续等待。如果 `recv` 函数返回 0,则说明服务器关闭了连接,此时需要退出循环。 希望这份代码能够对你有所帮助!

相关推荐

最新推荐

recommend-type

如何在C语言中判断socket是否已经断开

如果不主动关闭socket的话,系统不会自动关闭的,除非当前进程挂掉了,操作系统把占用的socket回收了才会关闭。小编今天跟大家简单介绍下如何在C语言中判断socket是否已经断开
recommend-type

如何基于C语言socket编程实现TCP通信

本文介绍了如何基于C语言socket编程实现TCP通信,下面小编来简单介绍下
recommend-type

C语言实现Linux下的socket文件传输实例

主要介绍了C语言实现Linux下的socket文件传输的方法,较为详细的分析了C语言文件Socket文件传输客户端与服务器端相关实现技巧,需要的朋友可以参考下
recommend-type

C语言实现socket简单通信实例

主要介绍了C语言实现socket简单通信的方法,是学习C语言网络编程非常基础而又实用的实例,需要的朋友可以参考下
recommend-type

socket多人聊天程序C语言版(一)

主要为大家详细介绍了socket多人聊天程序C语言版,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

可见光定位LED及其供电硬件具体型号,广角镜头和探测器,实验设计具体流程步骤,

1. 可见光定位LED型号:一般可使用5mm或3mm的普通白色LED,也可以选择专门用于定位的LED,例如OSRAM公司的SFH 4715AS或Vishay公司的VLMU3500-385-120。 2. 供电硬件型号:可以使用常见的直流电源供电,也可以选择专门的LED驱动器,例如Meanwell公司的ELG-75-C或ELG-150-C系列。 3. 广角镜头和探测器型号:一般可采用广角透镜和CMOS摄像头或光电二极管探测器,例如Omron公司的B5W-LA或Murata公司的IRS-B210ST01。 4. 实验设计流程步骤: 1)确定实验目的和研究对象,例如车辆或机器人的定位和导航。
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。