|
本帖最后由 Shaw0xyz 于 2024-5-25 13:05 编辑
1. 概述
网络编程是现代应用程序开发的基础,而套接字 (Socket) 是网络通信的核心。本文将详细介绍linux网络编程中的套接字,包括基本概念、常用函数以及实际案例。
2. 套接字基本概念
2.1. 什么是套接字
套接字是网络通信的端点,提供了应用程序之间在网络上传输数据的机制。它可以用于不同主机之间的通信,也可以用于同一主机上不同进程之间的通信。
2.2. 套接字类型
套接字主要分为以下几种类型:
- 流套接字 (SOCK_STREAM):提供面向连接的、可靠的字节流服务。典型协议是TCP。
- 数据报套接字 (SOCK_DGRAM):提供无连接的、不可靠的消息服务。典型协议是UDP。
2.3. 套接字地址
套接字地址包括IP地址和端口号。IP地址用于标识主机,端口号用于标识主机上的特定进程。
3. 套接字编程步骤
3.1. 创建套接字
使用`socket()`函数创建套接字。
- int sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0) {
- perror("socket");
- exit(EXIT_FAILURE);
- }
复制代码
#3.2. 绑定地址
使用`bind()`函数将套接字绑定到特定地址和端口。
- struct sockaddr_in server_addr;
- server_addr.sin_family = AF_INET;
- server_addr.sin_addr.s_addr = INADDR_ANY;
- server_addr.sin_port = htons(8080);
- if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
- perror("bind");
- exit(EXIT_FAILURE);
- }
复制代码
#3.3. 监听和接受连接
对于流套接字,需要使用`listen()`函数监听连接请求,使用`accept()`函数接受连接。
- if (listen(sockfd, 5) < 0) {
- perror("listen");
- exit(EXIT_FAILURE);
- }
- int client_sockfd = accept(sockfd, NULL, NULL);
- if (client_sockfd < 0) {
- perror("accept");
- exit(EXIT_FAILURE);
- }
复制代码
#3.4. 发送和接收数据
使用`send()`和`recv()`函数发送和接收数据。
- char buffer[1024];
- int bytes_received = recv(client_sockfd, buffer, sizeof(buffer), 0);
- if (bytes_received < 0) {
- perror("recv");
- exit(EXIT_FAILURE);
- }
- const char *message = "Hello, Client!";
- int bytes_sent = send(client_sockfd, message, strlen(message), 0);
- if (bytes_sent < 0) {
- perror("send");
- exit(EXIT_FAILURE);
- }
复制代码
#3.5. 关闭套接字
通信完成后,使用`close()`函数关闭套接字。
- close(client_sockfd);
- close(sockfd);
复制代码
4. 实际案例
#4.1. TCP服务器示例
以下是一个简单的TCP服务器示例,接受客户端连接并发送欢迎消息。
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- int main() {
- int sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0) {
- perror("socket");
- exit(EXIT_FAILURE);
- }
- struct sockaddr_in server_addr;
- server_addr.sin_family = AF_INET;
- server_addr.sin_addr.s_addr = INADDR_ANY;
- server_addr.sin_port = htons(8080);
- if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
- perror("bind");
- exit(EXIT_FAILURE);
- }
- if (listen(sockfd, 5) < 0) {
- perror("listen");
- exit(EXIT_FAILURE);
- }
- printf("Server listening on port 8080...\n");
- int client_sockfd = accept(sockfd, NULL, NULL);
- if (client_sockfd < 0) {
- perror("accept");
- exit(EXIT_FAILURE);
- }
- const char *message = "Welcome to the server!";
- if (send(client_sockfd, message, strlen(message), 0) < 0) {
- perror("send");
- exit(EXIT_FAILURE);
- }
- close(client_sockfd);
- close(sockfd);
- return 0;
- }
复制代码
#4.2. TCP客户端示例
以下是一个简单的TCP客户端示例,连接服务器并接收消息。
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- int main() {
- int sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0) {
- perror("socket");
- exit(EXIT_FAILURE);
- }
- struct sockaddr_in server_addr;
- server_addr.sin_family = AF_INET;
- server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- server_addr.sin_port = htons(8080);
- if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
- perror("connect");
- exit(EXIT_FAILURE);
- }
- char buffer[1024];
- if (recv(sockfd, buffer, sizeof(buffer), 0) < 0) {
- perror("recv");
- exit(EXIT_FAILURE);
- }
- printf("Received message: %s\n", buffer);
- close(sockfd);
- return 0;
- }
复制代码
5. 总结
通过本文,你应该对Linux网络编程中的套接字有了基本了解。套接字提供了强大的网络通信能力,可以用于构建各种网络应用程序。掌握套接字编程,可以让你在开发网络应用时游刃有余。希望这些示例代码能帮助你快速上手套接字编程,并应用到实际项目中。
|
|