I'm trying to implement TCP sockets where the client sends some data to the server and receives a response from the server. But right now my codes seem stuck at receiving data at the server.
This is my code for the server:
#define MAX_INPUT_SIZE 4000 #define EXIT_NOT_ON_VALUE(expression, value, message,exit_status) \ if ((expression)!=(value)) {\ fprintf(stderr,(message));\ exit((exit_status));\ } int main(int argc, char **argv){ int status, server_socket, client_number = 1; struct sockaddr_in address, client_address; int client_address_size; address.sin_family = AF_INET; address.sin_port = htons(argv[1]); address.sin_addr.s_addr = htonl(INADDR_ANY); server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); EXIT_ON_VALUE(server_socket, -1, "SOCKET CREATION FAILED, EXIT.\n", EXIT_FAILURE); status = bind(server_socket, (SA*)&address, sizeof(address)); EXIT_ON_VALUE(status, -1, "BIND FAILED, EXIT.\n", EXIT_FAILURE); status = listen(server_socket, MAX_LIS_QUEUE); EXIT_ON_VALUE(status, -1, "LISTEN CREATION FAILED, EXIT.\n", EXIT_FAILURE); while(1){ struct sockaddr_in client_address; socklen_t address_size; int client = accept(server_socket, (SA*)&client_address, &address_size); if (client==-1 && errno == EINTR) continue; EXIT_ON_VALUE(client, -1, "ACCEPT FAILED, EXIT.\n", EXIT_FAILURE); fprintf(stderr, "Accepted. Client No: %d. File No: %d\n", client_number, client); int child_pid = fork(); EXIT_ON_VALUE(child_pid, -1, "CHILD PROCESS CREATION FAILED, EXIT.\n", EXIT_FAILURE); if(child_pid==0){ char *row = malloc(MAX_INPUT_SIZE); EXIT_ON_VALUE(row, NULL, "CANNOT ALLOCATE MEMORY, EXIT. \n", EXIT_FAILURE); status = read_in_full(client, row, 20); EXIT_ON_VALUE(status, -1, "CANNOT READ, EXIT. \n", EXIT_FAILURE); printf("row data is:%s\n", row); /* modifying data operations... */ close(client); exit(EXIT_SUCCESS); } int result; wait(&result); char *msg = "NO PROBLEM!"; status = write_in_full(client, msg, strlen(msg)); } close(server_socket); exit(EXIT_SUCCESS); } This my code for the client:
#define MAX_INPUT_SIZE 4000 int main(int argc, char **argv) { int status; int connection; struct sockaddr_in address; char* data=malloc(4000); char* response=malloc(4000); printf("Data goes in?\n"); fgets(data, MAX_INPUT_SIZE, stdin); if ((strlen(data)>0) && (data[strlen(data)-1]=='\n')) data[strlen(data)-1] = '\0'; while (getchar()!='\n') ; address.sin_family = AF_INET; address.sin_port = htons(argv[1]); address.sin_addr.s_addr = htonl(INADDR_LOOPBACK); connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); EXIT_ON_VALUE(connection, -1, "Failed to create socket", EXIT_FAILURE); printf("FD is: %d\n", connection); status = connect(connection, (SA*) &address, sizeof(address)); EXIT_ON_VALUE(status, -1, "Connection failure", EXIT_FAILURE); status = write_in_full(connection, data, strlen(data)); if (status != -1) printf("Data sent!\n"); read_in_full(connection, data, MAX_INPUT_SIZE); printf("Response was %s\n", response); close(connection); exit(EXIT_SUCCESS); } Both read_in_full and write_in_full are functions try to avoid signal interrupt, they are implemented as follows:
int read_in_full(int fd, void *data, size_t size) { size_t total_read = 0; fprintf(stderr, "READING data.\n"); while (total_read < size) { int n_read = read(fd, data + total_read, size - total_read); if (n_read == -1) { if (errno == EINTR) continue; else return -1; } total_read += n_read; if (n_read == 0) return total_read; } return total_read; } int write_in_full(int fd, void *data, size_t size) { size_t total_written = 0; while (total_written < size) { int n_written = write(fd, data + total_written, size - total_written); if (n_written == -1) { if (errno == EINTR) continue; else return -1; } total_written += n_written; } return total_written; } What happened is:
- I start running the server, and it runs fine if there aren't any errors.
- I start running the client, and
Accepted. Client No: 1. File No: 4shows up which means my client has successfully connected to the server. - The client would print
Data goes in?and allow me to input a line of strings. - The client would print
Data sent!, and both server and client would printREADING data.which means they are calling theread_in_full()function and seems working. - Server stuck at this point. It doesn't read from the socket. At the main time, the client is waiting for a response.
- I closed the server with
ctrl+cand the client will printResponse was, obviously it doesn't receive anything.
This behaviour is so weird. Could someone help me on this, I'm so confused.
Thanks and appreciate!
https://stackoverflow.com/questions/66095024/in-c-tcp-sockets-hangs-and-behave-strange-when-sending-data February 08, 2021 at 09:58AM
没有评论:
发表评论