我有这个项目要为学校做,但我陷入困境。
编写一个使用 TCP 套接字进行通信的客户端-服务器应用程序。客户端向服务器发送一个短语,服务器用收到的字符串中的空格字符数进行应答。服务器返回一个二进制格式的整数 N(有符号),用 4 个字节表示,含义如下:
N >= 0 – the number of space characters in the received string;
N = -1 – error receiving the string, or the client does not respect the protocol;
N = -2 – if the count of spaces cannot be represented on 4 bytes (with sign) (i.e. greater that 231 -1). On 4 bytes the range of signed numbers that can be represented is -231 … +231-1.
我不明白为什么我在服务器中收到此错误:段错误(核心转储)
这是我的代码:
客户:
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define max 100
int main() {
int c, cod;
int32_t r;
struct sockaddr_in server;
char s[max];
c = socket(PF_INET, SOCK_STREAM, 0);
if (c < 0) {
fprintf(stderr, "Error creating socket client.\n");
return 1;
}
memset(&server, 0, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(4321);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
cod = connect(c, (struct sockaddr *) &server, sizeof(struct sockaddr_in));
if (cod < 0) {
fprintf(stderr, "Error connecting to server.\n");
return 1;
}
printf("Please insert a string to be sent: ");
fgets(s, max, stdin);
cod = send(c, s, strlen(s) + 1, 0);
if (cod != strlen(s) + 1) {
fprintf(stderr, "Error sending data to server.\n");
return 1;
}
cod = recv(c, &r, sizeof(int32_t), MSG_WAITALL);
r = ntohl(r);
if (cod != sizeof(int)) {
fprintf(stderr, "Error receiving data from server.\n");
return 1;
}
printf("Server returned %d space characters in the sent string.\n", r);
close(c);
}
服务器:
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
int c;
void time_out(int semnal) {
int32_t r = -1;
r = htonl(r);
printf("Time out.\n");
send(c, &r, sizeof(int32_t), 0);
close(c);
exit(1);
}
void tratare() {
int cod;
int32_t r;
uint8_t b;
struct sockaddr_in server;
if (c < 0) {
fprintf(stderr, "Error connecting with the client.\n");
exit(1);
}
else
printf("A new client connected.\n");
signal(SIGALRM, time_out);
alarm(10);
r = 0;
do {
cod = recv(c, &b, 1, 0);
printf("I received %d characters.\n", cod);
if (cod == 1)
alarm(10);
if (cod != 1) {
r = -1;
break;
}
if (b == ' ') {
if (r == INT32_MAX) {
r = -2;
break;
}
r++;
}
}
while (b != 0);
alarm(0);
r = htonl(r);
send(c, &r, sizeof(int32_t), 0);
r = ntohl(r);
close(c);
if (r >= 0)
printf("Connection closed. Sent %d spaces.\n", r);
else {
printf("Connection closed. Error code %d.\n", r);
exit(1);
}
exit(0);
}
int main() {
int s, l, cod;
struct sockaddr_in client, server;
s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
fprintf(stderr, "Error creating the socket server.\n");
return 1;
}
memset(&server, 0, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(4321);
server.sin_addr.s_addr = INADDR_ANY;
cod = bind(s, (struct sockaddr *) &server, sizeof(struct sockaddr_in));
if (cod < 0) {
fprintf(stderr, "Error on bind. Port is already used.\n");
return 1;
}
listen(s, 5);
while (1) {
memset(&client, 0, sizeof(client));
l = sizeof(client);
printf("Waiting for a client to connect.\n");
c = accept(s, (struct sockaddr *) &client, &l);
printf("Client connected with address %s and port %d.\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
if (fork() == 0) {
tratare();
}
}
}
最佳答案
您的服务器代码似乎缺少原型(prototype) inet_ntoa()
,因此编译器假定 int
作为返回值,其中应使用 char*
>,这至少在 64 位系统上是致命的,因为 int
是 32 位宽,而 char*
是 64 位宽,因此由 inet_ntoa() 返回的指针
一半的位被切断。
要修复此问题,请添加:
#include <arpa/inet.h>
在编译服务器源代码时,预计会发出如下警告:
warning: implicit declaration of function ‘inet_ntoa’ [-Wimplicit-function-declaration]
如果是这种情况,这里吸取的教训是:始终认真对待警告!
关于c - 段错误问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22450785/