2、套接字22-24
发布人:shili8
发布时间:2024-12-23 03:40
阅读次数:0
**套接字编程基础**
套接字(Socket)是计算机网络中的一种抽象概念,用于不同进程或程序之间的通信。它是一种特殊的文件描述符,可以通过网络传输数据包。套接字编程是构建网络应用的基本技能之一。
**2. 套接字类型**
在套接字编程中,我们可以创建四种类型的套接字:
* **TCP(面向连接)套接字**:这种套接字需要建立一个连接,然后才能传输数据。它保证了数据的可靠传输。
* **UDP(无连接)套接字**:这种套接字不需要建立连接,可以直接传输数据。但是,它不能保证数据的可靠传输。
* **RAW套接字**:这种套接字可以直接访问网络硬件,实现高性能的网络通信。
* **Unix域套接字**:这种套接字用于在同一台机器上不同进程之间的通信。
###2.1 TCP 套接字TCP(Transmission Control Protocol)是面向连接的协议,它保证了数据的可靠传输。下面是一个简单的例子:
c#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT8080int main() { int server_fd, client_fd; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[1024] = {0}; // 创建一个 TCP 套接字 if ((server_fd = socket(AF_INET, SOCK_STREAM,0)) ==0) { perror("socket failed"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // 绑定套接字 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 监听连接 if (listen(server_fd,3) < 0) { perror("listen failed"); exit(EXIT_FAILURE); } printf("Server listening on port %d... ", PORT); while (1) { // 等待客户端连接 client_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen); if (client_fd < 0) { perror("accept failed"); continue; } printf("Connected with client IP address %s and port %d... ", inet_ntoa(address.sin_addr), ntohs(address.sin_port)); // 接收数据 read(client_fd, buffer,1024); printf("%s ", buffer); // 回复数据 send(client_fd, "Hello from server!", strlen("Hello from server!"),0); // 关闭连接 close(client_fd); } return0; }
###2.2 UDP 套接字UDP(User Datagram Protocol)是无连接的协议,它不保证数据的可靠传输。下面是一个简单的例子:
c#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT8080int main() { int server_fd, client_fd; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[1024] = {0}; // 创建一个 UDP 套接字 if ((server_fd = socket(AF_INET, SOCK_DGRAM,0)) ==0) { perror("socket failed"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // 绑定套接字 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } printf("Server listening on port %d... ", PORT); while (1) { // 等待客户端数据包 recvfrom(server_fd, buffer,1024, MSG_WAITALL, (struct sockaddr *)&address, (socklen_t*)&addrlen); printf("%s ", buffer); // 回复数据 sendto(server_fd, "Hello from server!", strlen("Hello from server!"),0, (struct sockaddr *)&address, addrlen); } return0; }
###2.3 RAW 套接字RAW(Raw Socket)是直接访问网络硬件的套接字,实现高性能的网络通信。下面是一个简单的例子:
c#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT8080int main() { int server_fd, client_fd; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[1024] = {0}; // 创建一个 RAW 套接字 if ((server_fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) ==0) { perror("socket failed"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // 绑定套接字 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } printf("Server listening on port %d... ", PORT); while (1) { // 等待客户端数据包 recvfrom(server_fd, buffer,1024, MSG_WAITALL, (struct sockaddr *)&address, (socklen_t*)&addrlen); printf("%s ", buffer); // 回复数据 sendto(server_fd, "Hello from server!", strlen("Hello from server!"),0, (struct sockaddr *)&address, addrlen); } return0; }
###2.4 Unix域套接字Unix域套接字(Unix Domain Socket)是用于在同一台机器上不同进程之间的通信。下面是一个简单的例子:
c#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #define PATH "/tmp/unix_socket" int main() { int server_fd, client_fd; char buffer[1024] = {0}; // 创建一个 Unix域套接字 if ((server_fd = socket(AF_UNIX, SOCK_STREAM,0)) ==0) { perror("socket failed"); exit(EXIT_FAILURE); } struct sockaddr_un address; address.sun_family = AF_UNIX; strcpy(address.sun_path, PATH); // 绑定套接字 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } printf("Server listening on path %s... ", PATH); while (1) { // 等待客户端连接 client_fd = accept(server_fd, NULL, NULL); if (client_fd < 0) { perror("accept failed"); continue; } printf("Connected with client... "); // 接收数据 read(client_fd, buffer,1024); printf("%s ", buffer); // 回复数据 send(client_fd, "Hello from server!", strlen("Hello from server!"),0); // 关闭连接 close(client_fd); } return0; }
### 总结在本文中,我们介绍了套接字编程的基本概念和四种类型的套接字:TCP、UDP、RAW和Unix域套接字。我们提供了每种类型套接字的简单例子,帮助读者理解它们的使用场景和实现原理。