当前位置:实例文章 » 其他实例» [文章]2、套接字22-24

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域套接字。我们提供了每种类型套接字的简单例子,帮助读者理解它们的使用场景和实现原理。

其他信息

其他资源

Top