Я довольно новым для программирования сокетов, и у меня возникают проблемы отладки следующего кода:Странная перекручивание с сокетами
Клиент:
#define SIZE sizeof(struct sockaddr_in)
int main(int argc, char* argv[]) {
printf("Starting setup\n");
int sockfd;
int adder;
int sum;
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(7013);
inet_pton(AF_INET, "127.0.0.1", &server.sin_addr.s_addr);
printf("Setup complete\n");
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Socket call failed.\n");
return EXIT_FAILURE;
}
else{
printf("socket: %i", sockfd);
}
//connect the socket
if (connect(sockfd, (struct sockaddr*) &server, SIZE) == -1) {
perror("Connect call failed");
return EXIT_FAILURE;
}
//Send and receive
while (!feof(stdin)) {
printf("Input an integer \n");
adder = atoi(fgets(intChar, 11, stdin));
if ((send(sockfd, &adder, 11, 0)) == -1) {
perror("Send error");
}
if (recv(sockfd, &sum, 1, 0) > 0) {
printf("%d", sum);
}
else {
printf("Server has died \n");
close(sockfd);
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
Сервер:
int sum = 0;
int numconnections = 0;
int main(int argc, char* argv[]) {
int sockfd;
int newsockfd;
int adder = 0;
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(7013);
server.sin_addr.s_addr = INADDR_ANY;
printf("Starting up. \n");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
//Free port
int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (sockfd == -1) {
perror("Socket call failed. \n");
return EXIT_FAILURE;
}
//bind address
if (bind(sockfd, (struct sockaddr*) &server, sizeof(server)) == -1) {
perror("Bind call failed. \n");
return EXIT_FAILURE;
}
//listen
if (listen(sockfd, 5) == -1) {
perror("Listen call failed. \n");
return EXIT_FAILURE;
}
while (numconnections < 2) {
//accept a connection
printf("ready to accept connections\n");
if ((newsockfd = accept(sockfd, NULL, NULL)) == -1) {
perror("Accept call failed. \n");
continue;
}
printf("New connection detected");
numconnections++;
//spawn child to deal with it
if (fork() == 0) {
while (recv(newsockfd, &adder, 1, 0) > 0) {
printf("Sum is %d \n", sum);
printf("Adder is %d \n", adder);
sum += adder;
printf("Sending sum %d \n", sum);
send(newsockfd, &sum, 1, 0);
}
close(newsockfd);
return EXIT_SUCCESS;
}
}
close(newsockfd);
close(sockfd);
return EXIT_SUCCESS;
}
Независимо о том, запускаю ли я программы на одном компьютере или отдельно, когда сервер получает сокет, он продолжает добавлять числа примерно 10 раз подряд, почти так же, как если сокет зацикливается.
Вот некоторый пример вывод после того, как я представляю 3 от клиента:
Starting up.
ready to accept connections
New connection detectedready to accept connections
New connection detectedSum is 0
Adder is 3
Sending sum 3
Sum is 3
Adder is 0
Sending sum 3
Sum is 3
Adder is 0
Sending sum 3
Sum is 3
Adder is 0
Sending sum 3
Sum is 3
Adder is 77
Sending sum 80
Sum is 80
Adder is 11
Sending sum 91
Sum is 91
Adder is 64
Sending sum 155
Sum is 155
Adder is 0
Sending sum 155
Sum is 155
Adder is 3
Sending sum 158
Sum is 158
Adder is 0
Sending sum 158
Sum is 158
Adder is 0
Sending sum 158
На стороне клиента, я получаю обратно-сначала, но потом я получаю некоторый нонсенс номер как 4197123.
У меня есть сильное чувство, что я упускаю что-то очевидное. Заранее спасибо.
'while (recv (newsockfd, & adder, 1, 0)> 0) {' Использовать возвращаемое значение из recv() является последним фактически полученным байтом. Третий аргумент также неверен. – wildplasser
О, я вижу, третий аргумент для размера буфера, поэтому я должен использовать sizeof (int). –
По крайней мере. Или буфер между вызовами, что необходимо, поскольку TCP не имеет границ сообщений: поток может быть разбит в любой точке. – wildplasser