我有这个项目要为学校做,我被卡住了。
编写使用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.
我无法弄清楚为什么我在服务器中收到此错误:Segmentation fault(core dumped)
这是我的代码:
客户端:
#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();
}
}
}
答案 0 :(得分:1)
原型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]
如果是这种情况,这里吸取的教训是:始终严肃对待警告!