In C/C++, reading data from TCP sockets typically involves the following steps:
1. Creating and Configuring Sockets
First, create a socket and connect to the server. For example, use the socket() function to create the socket and then use connect() to establish the connection.
cint sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("Error creating socket"); exit(EXIT_FAILURE); } struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(port); inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("Error connecting to server"); exit(EXIT_FAILURE); }
2. Reading Data
Use the recv() or read() functions to read data from the socket. Both functions can read data from a connected socket, but recv() offers additional features such as message flags.
Using recv()
cchar buffer[1024]; ssize_t n_read = recv(sockfd, buffer, sizeof(buffer), 0); if (n_read < 0) { perror("Error reading from socket"); exit(EXIT_FAILURE); } else if (n_read == 0) { printf("Server closed the connection\n"); } else { printf("Received %ld bytes: %s\n", n_read, buffer); }
Using read()
cchar buffer[1024]; ssize_t n_read = read(sockfd, buffer, sizeof(buffer)); if (n_read < 0) { perror("Error reading from socket"); exit(EXIT_FAILURE); } else if (n_read == 0) { printf("Server closed the connection\n"); } else { printf("Received %ld bytes: %s\n", n_read, buffer); }
3. Handling TCP Stream Characteristics
In TCP communication, data segmentation and reassembly are handled automatically, so received data may not arrive in a single complete segment. It may be necessary to call recv() or read() multiple times to fully receive the expected data.
4. Closing the Socket
After data reading is complete, close the socket:
cclose(sockfd);
Summary
Properly reading data from TCP sockets requires looping the read functions until all data is received, handling various possible return values, and closing the socket at the end. Additionally, error handling is an indispensable part of implementation to ensure the program's robustness and stability.