引言
在网络编程的世界里,Socket编程就像是基石,是构建各种网络应用程序不可或缺的一环。在Linux环境下,Socket编程尤其重要,因为它为开发者提供了底层的网络通信接口。本文将带您轻松掌握Linux Socket编程的核心概念,学会收发命令,为您的网络编程之旅奠定坚实的基础。
Socket基础
什么是Socket?
Socket是网络通信的基石,它是一个通信端点,允许不同主机之间的进程进行通信。在Linux系统中,Socket可以分为流式Socket(如TCP)和数据报Socket(如UDP)两种。
Socket结构
一个Socket由四元组(IP地址、端口号、协议类型、连接状态)唯一标识。
Socket编程模型
- 阻塞式模型:当调用socket函数时,如果操作无法立即完成,进程会阻塞等待。
- 非阻塞式模型:进程在调用socket函数时不会阻塞,而是立即返回,通过轮询或其他机制检查操作是否完成。
TCP Socket编程
创建Socket
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int socket(int domain, int type, int protocol);
绑定地址
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
监听连接
#include <sys/socket.h>
int listen(int sockfd, int backlog);
接受连接
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
发送数据
#include <sys/socket.h>
#include <string.h>
int send(int sockfd, const void *buf, size_t len, int flags);
接收数据
#include <sys/socket.h>
int recv(int sockfd, void *buf, size_t len, int flags);
关闭Socket
#include <unistd.h>
int close(int sockfd);
UDP Socket编程
UDP Socket编程与TCP Socket编程类似,但有一些不同之处,如UDP不提供可靠传输,也没有连接建立和断开的过程。
创建Socket
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int socket(int domain, int type, int protocol);
发送数据
#include <sys/socket.h>
#include <string.h>
int sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
接收数据
#include <sys/socket.h>
#include <string.h>
int recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
关闭Socket
#include <unistd.h>
int close(int sockfd);
实战案例
客户端-服务器模型
// 服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
listen(sockfd, 5);
int newsockfd = accept(sockfd, NULL, NULL);
char buffer[1024];
read(newsockfd, buffer, 1024);
printf("Client: %s", buffer);
close(newsockfd);
close(sockfd);
return 0;
}
// 客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
char buffer[] = "Hello, Server!";
write(sockfd, buffer, strlen(buffer));
close(sockfd);
return 0;
}
总结
通过本文的介绍,相信您已经对Linux Socket编程有了初步的了解。Socket编程虽然复杂,但掌握了基本概念和编程模型后,就可以轻松实现网络通信。在今后的网络编程实践中,Socket编程将是您不可或缺的工具。祝您在编程道路上越走越远!