一、c socket 異步接收
c socket支持兩種類型的接收模式:阻塞模式和非阻塞模式,但是在大量的數據傳輸時,阻塞模式一定會造成數據的丟失和延遲,所以使用異步接收通常是一個更加可靠的解決辦法。在c++ socket中,我們可以使用select函數來實現異步接收。
while(1) { fd_set read_fds; FD_ZERO(&read_fds); FD_SET(sock_fd, &read_fds); if(select(sock_fd+1, &read_fds, NULL, NULL, NULL) <= 0) { continue; } if(FD_ISSET(sock_fd, &read_fds)) { recv(sock_fd, buffer, size, 0); } }
在上述代碼中,我們使用select函數監聽我們的socket,當有數據可讀時,便會進入recv函數來接收數據。
二、c socket 長連接
在網絡編程中,短連接是指每次請求都需要建立一個新的連接,而長連接則是可以一直保持連接狀態,在後續請求中都可以復用這個連接。
在c++ socket中,通過設置socket的選項SO_KEEPALIVE為1(開啟TCP心跳包機制)和TCP_NODELAY為1(禁用Nagle算法),我們可以實現長連接的功能。
int optval = 1; setsockopt(sock_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)); setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
三、c socket技術
c++ socket編程中需要使用到的技術包括:TCP/IP協議、Socket編程、多線程、select的應用、數據加密和壓縮等。以下是一個基本的c++ socket示例代碼,實現了TCP連接和發送一條消息的功能。
#include #include #include #include #include #include #include int main(int argc, char *argv[]) { int sock_fd; struct sockaddr_in server_addr; char msg[] = "Hello, world!"; // create socket sock_fd = socket(AF_INET, SOCK_STREAM, 0); if(sock_fd == -1) { perror("socket failed"); exit(EXIT_FAILURE); } // set server address server_addr.sin_family = AF_INET; server_addr.sin_port = htons(8080); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // connect to server if(connect(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("connect failed"); exit(EXIT_FAILURE); } // send message if(send(sock_fd, msg, strlen(msg), 0) < 0) { perror("send failed"); exit(EXIT_FAILURE); } // close socket close(sock_fd); return 0; }
四、c socket通訊源代碼
以下是一個基於select函數實現的簡單通信源代碼,包括服務器端和客戶端。
服務器端
#include #include #include #include #include #include #include int main(int argc, char *argv[]) { int listen_fd, max_fd, client_fd[FD_SETSIZE], conn_fd; int nready; struct sockaddr_in server_addr, client_addr; socklen_t client_len; char buffer[256]; fd_set read_set, all_set; int i; // create listen socket listen_fd = socket(AF_INET, SOCK_STREAM, 0); if(listen_fd == -1) { perror("socket failed"); exit(EXIT_FAILURE); } // set server address server_addr.sin_family = AF_INET; server_addr.sin_port = htons(8080); server_addr.sin_addr.s_addr = htons(INADDR_ANY); // bind listen_fd if(bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // listen to client requests if(listen(listen_fd, 10) < 0) { perror("listen failed"); exit(EXIT_FAILURE); } max_fd = listen_fd; for(i = 0; i < FD_SETSIZE; i++) client_fd[i] = -1; FD_ZERO(&all_set); FD_SET(listen_fd, &all_set); printf("Server running...\n"); while(1) { read_set = all_set; nready = select(max_fd+1, &read_set, NULL, NULL, NULL); if(nready < 0) { perror("select failed"); exit(EXIT_FAILURE); } // if new client request if(FD_ISSET(listen_fd, &read_set)) { client_len = sizeof(client_addr); conn_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &client_len); if(conn_fd < 0) { perror("accept failed"); continue; } for(i = 0; i < FD_SETSIZE; i++) { if(client_fd[i] max_fd) { max_fd = conn_fd; } } for(i = 0; i < FD_SETSIZE; i++) { if(client_fd[i] < 0) continue; if(FD_ISSET(client_fd[i], &read_set)) { memset(buffer, 0, sizeof(buffer)); if(read(client_fd[i], buffer, sizeof(buffer)-1) == 0) { printf("client[%d] closed\n", i); close(client_fd[i]); FD_CLR(client_fd[i], &all_set); client_fd[i] = -1; } else { printf("recv from client[%d]: %s\n", i, buffer); } } } } // close listen_fd close(listen_fd); return 0; }
客戶端
#include #include #include #include #include #include int main(int argc, char *argv[]) { int sock_fd; struct sockaddr_in server_addr; char buffer[256]; // create socket sock_fd = socket(AF_INET, SOCK_STREAM, 0); if(sock_fd == -1) { perror("socket failed"); exit(EXIT_FAILURE); } // set server address server_addr.sin_family = AF_INET; server_addr.sin_port = htons(8080); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // connect to server if(connect(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("connect failed"); exit(EXIT_FAILURE); } // send message strcpy(buffer, "Hello, world!"); send(sock_fd, buffer, strlen(buffer), 0); printf("send message: %s\n", buffer); // close socket close(sock_fd); return 0; }
五、c socket設置阻塞
在c++ socket編程中,我們默認使用阻塞模式來進行通信,即當進行讀寫操作時,程序將一直等待,直到I/O操作完成或者到達超時時間。
阻塞模式可以通過設置socket的O_NONBLOCK選項來實現非阻塞模式:
int flags = fcntl(sock_fd, F_GETFL, 0); fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);
六、c socket傳輸
c++ socket中傳輸數據通常是通過send和recv函數進行。以下是一個基本的發送和接收數據的示例代碼:
發送數據
char buffer[256]; strcpy(buffer, "Hello, world!"); send(sock_fd, buffer, strlen(buffer), 0);
接收數據
char buffer[256]; memset(buffer, 0, sizeof(buffer)); recv(sock_fd, buffer, sizeof(buffer)-1, 0); printf("recv message: %s\n", buffer);
七、c socket編程基礎
c++ socket編程的基礎可以分為以下幾個方面:
1. c socket 構造
c++ socket的構造需要使用socket函數,該函數包括三個參數:地址族、套接字類型和協議。
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
2. c socket函數
c++ socket編程需要使用一些關鍵的函數,包括bind、listen、accept、connect、send和recv等。以下是這些函數的基本使用方法:
bind函數
將socket與地址綁定:
struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(8080); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); bind(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
listen函數
告訴socket開始監聽連接請求:
listen(sock_fd, 10);
accept函數
接受客戶端的連接請求:
struct sockaddr_in client_addr; int client_fd = accept(sock_fd, (struct sockaddr*)&client_addr, &client_len);
connect函數
向服務器發起連接請求:
struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(8080); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); connect(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
send函數
發送數據到對端:
char buffer[256]; strcpy(buffer, "Hello, world!"); send(sock_fd, buffer, strlen(buffer), 0);
recv函數
從對端接收數據:
char buffer[256]; memset(buffer, 0, sizeof(buffer)); recv(sock_fd, buffer, sizeof(buffer)-1, 0); printf("recv message: %s\n", buffer);
3. c語言socket通信
在c++ socket編程中,使用的通信協議通常是TCP/IP。
TCP/IP協議採用了面向連接的方式進行通信,可以保證數據的可靠性和完整性。但是,相比於UDP協議,TCP/IP協議的速度會稍微慢一些。
c++ socket編程中應用廣泛的通信方式有:單客戶端單線程、單客戶端多線程、多客戶端單線程和多客戶端多線程。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/271379.html