UNIX套接字编程接口:READ/WRITE操作

需积分: 46 2 下载量 170 浏览量 更新于2024-07-12 收藏 1.83MB PPT 举报
本文主要讨论了网络编程中的读/写套接字操作,即READ()和WRITE()函数,并介绍了套接字编程接口在UNIX系统中的发展和应用。套接字是应用程序与协议栈软件进行通信的桥梁,使得开发者能方便地编写客户与服务器软件。 在面对如何使应用程序更方便地利用协议栈进行通信的问题时,套接字应用程序编程接口(Socket API)应运而生。这一接口起源于加州大学伯克利分校开发的BSD UNIX操作系统,并逐渐被其他操作系统采纳。套接字API定义了一组操作,让应用程序能够控制协议栈,实现各种网络功能,同时影响了程序开发的难易程度。 套接字编程接口有两种实现方式:一是直接在操作系统内核中增加相应的软件;二是通过外部函数库来实现。在UNIX系统中,套接字被整合到统一的I/O模型中,即"打开-读-写-关闭"模式。尽管如此,由于网络通信的复杂性,简单的open、read、write、close四步操作不足以应对,因此套接字API设计了更多的函数来处理网络通信中的各种细节。 READ()和WRITE()函数是套接字编程接口中用于读取和写入数据的关键函数。READ()函数接收三个参数:套接字描述符sockfd、数据缓冲区buffer和缓冲区长度len,它从套接字中读取数据到指定的缓冲区。WRITE()函数同样需要这三个参数,但它的作用是将缓冲区中的数据写入到指定的套接字。这两个函数是进行网络数据传输的基础。 在实现套接字通信时,还需要处理诸如连接建立、地址解析、错误处理等额外步骤,这通常涉及到更多套接字函数,如bind()、listen()、accept()、connect()、send()和recv()等。这些函数共同构建了丰富的套接字编程接口,使得开发者能够灵活地创建各种复杂的网络应用。 套接字和其相关的READ()和WRITE()函数是网络编程中的核心工具,它们使得开发者能够在各种操作系统上构建跨平台的网络服务,促进了互联网的繁荣和发展。通过深入理解和熟练运用这些接口,开发者可以创建出高效、稳定的网络应用程序。

下面的代码修改一下 需要支持https双向认证int https_post(const char *cert_path, const char *url, const char *body, char *response) { int sockfd, len; struct sockaddr_in dest; struct hostent *host; SSL_CTX *ctx; SSL ssl; char request[MAX_BUF_SIZE], buf[MAX_BUF_SIZE]; // 初始化OpenSSL库 SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); // 解析主机名 //printf("66666666 %s\n", url); char hostname[2560]; getHostFromURL(url, hostname); host = gethostbyname(hostname); if (host == NULL) { perror("gethostbyname"); return -1; } // 创建套接字 sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); return -1; } // 设置目标地址 bzero(&dest, sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(443); dest.sin_addr.s_addr = (long)host->h_addr; // 连接服务器 if (connect(sockfd, (struct sockaddr)&dest, sizeof(dest)) != 0) { perror("connect"); return -1; } ctx = SSL_CTX_new(TLS_method()); // 设置支持的协议版本为 TLSv1.2 SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); if (ctx == NULL) { perror("SSL_CTX_new"); return -1; } // 加载证书 if (SSL_CTX_load_verify_locations(ctx, cert_path, NULL) != 1) { perror("SSL_CTX_load_verify_locations"); return -1; } // 创建SSL ssl = SSL_new(ctx); if (ssl == NULL) { perror("SSL_new"); return -1; } // 将套接字绑定到SSL SSL_set_fd(ssl, sockfd); // SSL握手 if (SSL_connect(ssl) == -1) { perror("SSL_connect"); return -1; } // 构造HTTP请求 char *escaped_url = urlencode(url); sprintf(request, "POST / HTTP/1.1\r\n" "Host: %s\r\n" "Content-Type: application/json\r\n" "Content-Length: %d\r\n" "\r\n" "%s", escaped_url, strlen(body), body); // 发送HTTP请求 SSL_write(ssl, request, strlen(request)); // 接收HTTP响应 len = SSL_read(ssl, buf, MAX_BUF_SIZE); printf("response %s\n", buf); // 关闭SSL和套接字 SSL_free(ssl); close(sockfd); // 处理响应 strncpy(response, buf, len); printf("Child process created with PID %d\n", 60909); response[len] = '\0'; printf("Child process created with PID %d\n", 70909); // 清理OpenSSL库 SSL_CTX_free(ctx); EVP_cleanup(); printf("Child process created with PID %d\n", 909); free(escaped_url); return 0; }

2023-06-01 上传