一、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-tw/n/271379.html
微信掃一掃
支付寶掃一掃