本篇文章来讲一下linux网络编程
Linux网络编程是指在Linux操作系统上进行网络通信的应用程序开发。它涉及使用套接字(Sockets)来创建客户端和服务器应用程序,以实现跨网络的数据传输和通信。
以下是Linux网络编程的一些基本概念:
- 套接字(Sockets):套接字是网络通信的端点。它提供了一个编程接口,使应用程序能够通过网络发送和接收数据。套接字可以分为不同类型的,如流套接字(SOCK_STREAM,用于TCP协议)和数据报套接字(SOCK_DGRAM,用于UDP协议)。
- IP地址和端口号:IP地址是计算机在网络上的唯一标识,而端口号则是计算机上运行的程序用于网络通信的标识。当应用程序想要建立网络连接时,它需要指定要连接的IP地址和端口号。
- 套接字编程:套接字编程涉及使用特定的系统调用来创建、连接、读写和关闭套接字。常见的套接字编程函数包括
socket()
、bind()
、listen()
、accept()
、connect()
、send()
、recv()
等。- 客户端/服务器架构:在网络编程中,通常使用客户端/服务器架构。服务器应用程序在特定端口上监听连接请求,而客户端应用程序则连接到服务器以发送和接收数据。
- 阻塞与非阻塞套接字:套接字可以分为阻塞和非阻塞两种模式。在阻塞模式下,套接字操作会阻塞调用线程的执行,直到操作完成。而在非阻塞模式下,套接字操作会立即返回,无论操作是否完成。
- 并发与多线程:为了提高服务器的性能,通常需要使用并发技术来处理多个客户端连接。这可以通过多线程、多进程或异步I/O等方式实现。
- 协议:网络编程中常用的协议包括TCP(传输控制协议)和UDP(用户数据报协议)。TCP提供可靠的、有序的、基于字节流的传输服务,而UDP则提供无连接的、不可靠的、基于数据报的传输服务。
以下是一个简单的 Linux 套接字编程案例,使用 C++ 实现。这个案例将展示一个基本的 TCP 服务器和客户端,服务器接收客户端发送的消息并回应。
首先是 TCP 服务器的代码:
// TCPServer.cpp
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
const int PORT = 8080;
const int BUFFER_SIZE = 1024;
int main() {
int serverSocket, clientSocket;
struct sockaddr_in serverAddr, clientAddr;
char buffer[BUFFER_SIZE];
socklen_t addrLen = sizeof(clientAddr);
// 创建套接字
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket < 0) {
std::cerr << "Error creating socket" << std::endl;
return -1;
}
// 初始化服务器地址结构
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(PORT);
// 绑定套接字到地址
if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
std::cerr << "Error binding socket" << std::endl;
close(serverSocket);
return -1;
}
// 开始监听
if (listen(serverSocket, 5) < 0) {
std::cerr << "Error listening on socket" << std::endl;
close(serverSocket);
return -1;
}
std::cout << "Server listening on port " << PORT << "..." << std::endl;
// 接受客户端连接
clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &addrLen);
if (clientSocket < 0) {
std::cerr << "Error accepting socket" << std::endl;
close(serverSocket);
return -1;
}
std::cout << "Client connected" << std::endl;
// 接收和发送消息
int bytesRead = recv(clientSocket, buffer, BUFFER_SIZE, 0);
if (bytesRead < 0) {
std::cerr << "Error receiving data" << std::endl;
close(clientSocket);
close(serverSocket);
return -1;
}
std::cout << "Received from client: " << buffer << std::endl;
const char* response = "Message received!";
send(clientSocket, response, strlen(response), 0);
std::cout << "Response sent to client" << std::endl;
// 关闭套接字
close(clientSocket);
close(serverSocket);
return 0;
}
TCP 客户端的代码:
// TCPClient.cpp
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
const char* SERVER_IP = "127.0.0.1";
const int PORT = 8080;
const int BUFFER_SIZE = 1024;
int main() {
int clientSocket;
struct sockaddr_in serverAddr;
char buffer[BUFFER_SIZE];
// 创建套接字
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket < 0) {
std::cerr << "Error creating socket" << std::endl;
return -1;
}
// 初始化服务器地址结构
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(SERVER_IP);
serverAddr.sin_port = htons(PORT);
// 连接到服务器
if (connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
std::cerr << "Error connecting to server" << std::
TCP 服务器
功能
- 服务器监听指定的端口(在这个例子中是 8080)。
- 接受来自客户端的连接请求。
- 接收客户端发送的消息。
- 回应客户端的消息。
- 关闭连接。
代码结构
变量声明:定义服务器套接字(
serverSocket
),客户端套接字(clientSocket
),服务器地址(serverAddr
),客户端地址(clientAddr
),以及接收数据的缓冲区(buffer
)。创建套接字:使用
socket()
函数创建一个新的套接字。绑定套接字:使用
bind()
函数将套接字绑定到服务器的 IP 地址和端口。开始监听:使用
listen()
函数开始监听连接请求。接受连接:使用
accept()
函数接受客户端的连接请求,并返回一个新的套接字用于与客户端通信。接收数据:使用
recv()
函数从客户端接收数据。发送响应:使用
send()
函数向客户端发送响应。关闭套接字:使用
close()
函数关闭客户端套接字和服务器套接字。TCP 客户端
功能
- 连接到指定的服务器和端口(在这个例子中是本机的 8080 端口)。
- 向服务器发送消息。
- 接收服务器的响应。
- 关闭连接。
代码结构
变量声明:定义客户端套接字(
clientSocket
),服务器地址(serverAddr
),以及发送和接收数据的缓冲区(buffer
)。创建套接字:使用
socket()
函数创建一个新的套接字。连接到服务器:使用
connect()
函数连接到服务器的 IP 地址和端口。发送数据:使用
send()
函数向服务器发送数据。接收响应:使用
recv()
函数从服务器接收响应。关闭套接字:使用
close()
函数关闭客户端套接字。
总结:网络编程的核心无非就是使用网络协议 然后将服务端和客户端连接起来 实现协议的通信 一般都是多个客户端 一个服务端 然后加上数据库来存储数据