一、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/n/271379.html
 
 微信扫一扫
微信扫一扫  支付宝扫一扫
支付宝扫一扫 