一、基礎概念
Linux網路編程涉及到一些基礎概念,包括Socket、IP地址、埠等。Socket是Linux網路編程的核心,它是應用程序與網路協議之間的介面,可以進行網路通信。IP地址是網路中唯一標識一個主機的數值地址,通過它可以進行網路通信。而埠是用於標識一個應用程序的地址,只有在同一IP地址下,不同埠的應用程序才能進行通信。
下面是基於Socket的簡單TCP伺服器端代碼示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
// 創建socket
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
// 設置socket運行參數
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;
// 綁定socket
bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address));
// 監聽socket
listen(server_socket, 5);
// 等待客戶端連接
int client_socket = accept(server_socket, NULL, NULL);
// 向客戶端發送消息
char message[] = "Hello, World!";
send(client_socket, message, sizeof(message), 0);
// 關閉socket
close(client_socket);
close(server_socket);
return 0;
}
二、套接字編程
Linux網路編程中,套接字編程是最常用的編程方式。套接字編程使用Socket介面,通過系統調用Bind、Listen、Accept、Connect、Recv、Send等方法實現網路通信,包括TCP、UDP、Raw Socket等多種協議。
下面是基於Socket的簡單TCP客戶端代碼示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
// 創建socket
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
// 設置socket運行參數
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
inet_pton(AF_INET, "127.0.0.1", &server_address.sin_addr);
// 連接伺服器
connect(client_socket, (struct sockaddr*)&server_address, sizeof(server_address));
// 接收伺服器消息
char message[100];
recv(client_socket, message, 100, 0);
// 輸出伺服器消息
printf("%s\n", message);
// 關閉socket
close(client_socket);
return 0;
}
三、網路通信協議
一個網路應用系統中,各個層次之間通信需要遵循不同的協議,包括物理層協議、數據鏈路層協議、網路層協議、傳輸層協議和應用層協議。Linux網路編程涉及到的主要協議有TCP/IP協議、UDP協議、ICMP協議、ARP協議等。其中,TCP/IP協議是最常用的網路通信協議,它實現了可靠的數據傳輸,可以確保數據的正確性。
下面是基於Socket的簡單UDP伺服器端代碼示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
// 創建socket
int server_socket = socket(AF_INET, SOCK_DGRAM, 0);
// 設置socket運行參數
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9003);
server_address.sin_addr.s_addr = INADDR_ANY;
// 綁定socket
bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address));
// 接收客戶端消息
char message[100];
struct sockaddr_in client_address;
socklen_t client_length = sizeof(client_address);
recvfrom(server_socket, message, 100, 0, (struct sockaddr*)&client_address, &client_length);
// 輸出客戶端IP地址及消息內容
printf("Message from [%s]: %s\n", inet_ntoa(client_address.sin_addr), message);
// 關閉socket
close(server_socket);
return 0;
}
下面是基於Socket的簡單UDP客戶端代碼示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
// 創建socket
int client_socket = socket(AF_INET, SOCK_DGRAM, 0);
// 設置socket運行參數
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9003);
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
// 發送消息到伺服器
char message[] = "Hello, server!";
sendto(client_socket, message, sizeof(message), 0, (struct sockaddr*)&server_address, sizeof(server_address));
// 關閉socket
close(client_socket);
return 0;
}
四、多線程網路編程
多線程網路編程是指在一個進程中,啟動多個線程來處理網路請求。它可以提高程序並發處理能力,同時也需要注意線程間的同步、互斥等問題。
下面是基於Socket的簡單多線程TCP伺服器端代碼示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
void* handle_client(void* arg)
{
// 接收客戶端消息
char message[100];
int client_socket = *((int*)arg);
recv(client_socket, message, 100, 0);
// 輸出客戶端消息
printf("%s\n", message);
// 向客戶端發送消息
char reply[] = "I have received your message!";
send(client_socket, reply, sizeof(reply), 0);
// 關閉socket
close(client_socket);
return NULL;
}
int main()
{
// 創建socket
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
// 設置socket運行參數
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9004);
server_address.sin_addr.s_addr = INADDR_ANY;
// 綁定socket
bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address));
// 監聽socket
listen(server_socket, 5);
// 創建線程處理客戶端請求
pthread_t thread_id;
while(1)
{
int client_socket = accept(server_socket, NULL, NULL);
pthread_create(&thread_id, NULL, handle_client, &client_socket);
}
// 關閉socket
close(server_socket);
return 0;
}
五、網路安全編程
Linux網路編程中,網路安全編程是十分重要的內容。網路安全編程主要包括SSL/TLS協議、數字簽名、加解密等技術,可以保證網路通信的安全性。
下面是基於SSL/TLS協議的簡單TCP伺服器端代碼示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
void init_openssl()
{
SSL_library_init();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
}
void cleanup_openssl()
{
ERR_free_strings();
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
}
SSL_CTX* create_context()
{
const SSL_METHOD* method;
SSL_CTX* ctx;
method = TLSv1_2_server_method();
ctx = SSL_CTX_new(method);
if (!ctx)
{
perror("Unable to create SSL context");
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
return ctx;
}
void configure_context(SSL_CTX* ctx)
{
SSL_CTX_set_ecdh_auto(ctx, 1);
if (SSL_CTX_use_certificate_file(ctx, "cert.pem", SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
if (SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM) <= 0 )
{
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
}
int main()
{
// 初始化OpenSSL
SSL_CTX* ctx;
init_openssl();
ctx = create_context();
configure_context(ctx);
// 創建socket
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
// 設置socket運行參數
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9005);
server_address.sin_addr.s_addr = INADDR_ANY;
// 綁定socket
bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address));
// 監聽socket
listen(server_socket, 5);
// 接收客戶端連接並進行SSL握手
while(1)
{
struct sockaddr_in client_address;
unsigned int client_length = sizeof(client_address);
int client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_length);
SSL* ssl = SSL_new(ctx);
SSL_set_fd(ssl, client_socket);
if (SSL_accept(ssl) <= 0)
{
ERR_print_errors_fp(stderr);
}
else
{
// 向客戶端發送消息
char message[] = "Hello, World!";
SSL_write(ssl, message, sizeof(message));
// 接收客戶端消息
char buffer[100];
SSL_read(ssl, buffer, 100);
printf("Client message: %s\n", buffer);
}
// 關閉SSL連接
SSL_shutdown(ssl);
SSL_free(ssl);
// 關閉socket
close(client_socket);
}
// 關閉socket
close(server_socket);
// 清理OpenSSL
cleanup_openssl();
return 0;
}
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/240271.html
微信掃一掃
支付寶掃一掃