写入服务器 returns 无
Writing to server returns nothing
下面是一个名为 Marvin 的聊天客户端的片段,如果有人说 "Hey Marvin, 1+1",程序将发送到服务器 "Hey user, 2"。问题是,即使输出可以正确打印客户端大小,当我尝试使用 write() 将它发送到服务器时,服务器也只是得到 "Marvin:"
关于我的 write() 为何不起作用的任何想法?我突出显示了我使用 write 的区域,但它们在第二个功能中,中途。辅助函数有很多,所以我把它们删减并解释它们通常的作用。
static int sockfd;
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "usage: %s hostname [port number] ...\n", argv[0]);
return(1);
}
//INITIALIZERS
//int sockfd;
fd_set master;
char buf[500];
struct hostent *hp;
struct sockaddr_in peer;
char *name = malloc(MAXHANDLE);
char *todo = malloc(MAXMESSAGE); /*
extern void reply(char *buf, char *name);
extern char *myreadline(struct client *p);
struct client *p = malloc(sizeof(struct client));
extern int tracer(char *str, int start, int len);
extern int choice(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
*/
//HOST
if ((hp = gethostbyname(argv[1])) == NULL) {
fprintf(stderr, "%s: no such host\n", argv[1]);
return(1);
}
if (hp->h_addr_list[0] == NULL || hp->h_addrtype != AF_INET) {
fprintf(stderr, "%s: not an internet protocol host name\n", argv[1]);
return(1);
}
//SOCKET
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(1);
}
memset(&peer, '[=11=]', sizeof peer);
peer.sin_family = AF_INET;
peer.sin_addr.s_addr = INADDR_ANY;
//PORT
if (argc > 2) {
if (!(port = atoi(argv[2])) == 0) {
peer.sin_port = htons(port);
} else {
fprintf(stderr, "%s: port number must be a positive integer\n", argv[0]);
return(1);
}
} else {
peer.sin_port = htons(1234);
}
//SOCKET
peer.sin_addr = *((struct in_addr*)(hp->h_addr));
if (connect(sockfd, (struct sockaddr *)&peer, sizeof(peer)) == -1) {
perror("connect");
close(sockfd);
exit(1);
}
FD_ZERO(&master);
FD_SET(STDIN_FILENO, &master);
FD_SET(sockfd, &master);
fd_set fds;
//BANNER HANDLE
//FILLS *p WITH INFORMATION of server
//*p = addclient(sockfd);
char *buff = malloc(500);
while (1) {
//READS A LINE
//buff = myreadline(p);
if (buff == NULL)
continue;
if (!strcmp(buff, CHATSVR_ID_STRING)) {
write(sockfd, "Marvin", MAXHANDLE);
break;
} else {
fprintf(stderr, "%s: invalid chatsvr\n", buff);
exit(1);
}
}
//LOOP
while(1) {
fds = master;
//RUNS SELECT WITH ERROR CHECKING
choice(sockfd+1, &fds, NULL, NULL, NULL);
if(FD_ISSET(STDIN_FILENO, &fds)) {
fgets(buf, sizeof buf, stdin);
if (strlen(buf) > 0) {
reply(buf, "Marvin");
}
} else if (FD_ISSET(sockfd, &fds)) {
//name = myreadline(p);
if (name != NULL) {
printf("%s\n", name);
strtok_r(name, ": ", &todo);
//tracer(todo, 0, 1);
reply(todo, name);
}
}
}
return(0);
}
//Given name and command, prints required output
void reply(char *buf, char *name) {
//extern int tracer(char *str, int start, int len);
//extern int tinder(const char *a, const char *b);
char *replied = buf;
if (strlen(buf) > 0) {
if (!tinder(buf, "Hey Marvin,")) {
printf("%s\n", replied);
//ISSUE HERE XXX
write(sockfd, replied, sizeof(replied));
return;
} else {
tracer(buf, 0, 11);
}
struct expr *e = parse(buf);
if (e) {
sprintf(replied, "Marvin: Hey %s, %d\n", name, evalexpr(e));
printf("%s\n", replied);
//ISSUE HERE
write(sockfd, replied, sizeof(replied));
freeexpr(e);
} else {
sprintf(replied, "Marvin: Hey %s, I don't like that.\n[%s]\n", name, errorstatus);
printf("%s\n", replied);
//XXX ISSUE HERE
write(sockfd, replied, sizeof(replied));
}
}
}
从客户端,我发送:
chatsvr: Welcome to our new participant, Marvin
hi
dsha
^C
服务器端,显示如下:
chatsvr: Welcome to our new participant, Marvin
Marvin:
Marvin:
Marvin:
chatsvr: Goodbye, Marvin
什么时候应该是:
chatsvr: Welcome to our new participant, Marvin
Marvin: hi
Marvin: dsha
chatsvr: Goodbye, Marvin
//ISSUE HERE XXX
write(sockfd, replied, sizeof(replied));
这里你应该使用strlen(replied)
而不是sizeof
。
确保在将接收到的字符串用作字符串之前以空字符结尾。
下面是一个名为 Marvin 的聊天客户端的片段,如果有人说 "Hey Marvin, 1+1",程序将发送到服务器 "Hey user, 2"。问题是,即使输出可以正确打印客户端大小,当我尝试使用 write() 将它发送到服务器时,服务器也只是得到 "Marvin:"
关于我的 write() 为何不起作用的任何想法?我突出显示了我使用 write 的区域,但它们在第二个功能中,中途。辅助函数有很多,所以我把它们删减并解释它们通常的作用。
static int sockfd;
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "usage: %s hostname [port number] ...\n", argv[0]);
return(1);
}
//INITIALIZERS
//int sockfd;
fd_set master;
char buf[500];
struct hostent *hp;
struct sockaddr_in peer;
char *name = malloc(MAXHANDLE);
char *todo = malloc(MAXMESSAGE); /*
extern void reply(char *buf, char *name);
extern char *myreadline(struct client *p);
struct client *p = malloc(sizeof(struct client));
extern int tracer(char *str, int start, int len);
extern int choice(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
*/
//HOST
if ((hp = gethostbyname(argv[1])) == NULL) {
fprintf(stderr, "%s: no such host\n", argv[1]);
return(1);
}
if (hp->h_addr_list[0] == NULL || hp->h_addrtype != AF_INET) {
fprintf(stderr, "%s: not an internet protocol host name\n", argv[1]);
return(1);
}
//SOCKET
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(1);
}
memset(&peer, '[=11=]', sizeof peer);
peer.sin_family = AF_INET;
peer.sin_addr.s_addr = INADDR_ANY;
//PORT
if (argc > 2) {
if (!(port = atoi(argv[2])) == 0) {
peer.sin_port = htons(port);
} else {
fprintf(stderr, "%s: port number must be a positive integer\n", argv[0]);
return(1);
}
} else {
peer.sin_port = htons(1234);
}
//SOCKET
peer.sin_addr = *((struct in_addr*)(hp->h_addr));
if (connect(sockfd, (struct sockaddr *)&peer, sizeof(peer)) == -1) {
perror("connect");
close(sockfd);
exit(1);
}
FD_ZERO(&master);
FD_SET(STDIN_FILENO, &master);
FD_SET(sockfd, &master);
fd_set fds;
//BANNER HANDLE
//FILLS *p WITH INFORMATION of server
//*p = addclient(sockfd);
char *buff = malloc(500);
while (1) {
//READS A LINE
//buff = myreadline(p);
if (buff == NULL)
continue;
if (!strcmp(buff, CHATSVR_ID_STRING)) {
write(sockfd, "Marvin", MAXHANDLE);
break;
} else {
fprintf(stderr, "%s: invalid chatsvr\n", buff);
exit(1);
}
}
//LOOP
while(1) {
fds = master;
//RUNS SELECT WITH ERROR CHECKING
choice(sockfd+1, &fds, NULL, NULL, NULL);
if(FD_ISSET(STDIN_FILENO, &fds)) {
fgets(buf, sizeof buf, stdin);
if (strlen(buf) > 0) {
reply(buf, "Marvin");
}
} else if (FD_ISSET(sockfd, &fds)) {
//name = myreadline(p);
if (name != NULL) {
printf("%s\n", name);
strtok_r(name, ": ", &todo);
//tracer(todo, 0, 1);
reply(todo, name);
}
}
}
return(0);
}
//Given name and command, prints required output
void reply(char *buf, char *name) {
//extern int tracer(char *str, int start, int len);
//extern int tinder(const char *a, const char *b);
char *replied = buf;
if (strlen(buf) > 0) {
if (!tinder(buf, "Hey Marvin,")) {
printf("%s\n", replied);
//ISSUE HERE XXX
write(sockfd, replied, sizeof(replied));
return;
} else {
tracer(buf, 0, 11);
}
struct expr *e = parse(buf);
if (e) {
sprintf(replied, "Marvin: Hey %s, %d\n", name, evalexpr(e));
printf("%s\n", replied);
//ISSUE HERE
write(sockfd, replied, sizeof(replied));
freeexpr(e);
} else {
sprintf(replied, "Marvin: Hey %s, I don't like that.\n[%s]\n", name, errorstatus);
printf("%s\n", replied);
//XXX ISSUE HERE
write(sockfd, replied, sizeof(replied));
}
}
}
从客户端,我发送:
chatsvr: Welcome to our new participant, Marvin
hi
dsha
^C
服务器端,显示如下:
chatsvr: Welcome to our new participant, Marvin
Marvin:
Marvin:
Marvin:
chatsvr: Goodbye, Marvin
什么时候应该是:
chatsvr: Welcome to our new participant, Marvin
Marvin: hi
Marvin: dsha
chatsvr: Goodbye, Marvin
//ISSUE HERE XXX
write(sockfd, replied, sizeof(replied));
这里你应该使用strlen(replied)
而不是sizeof
。
确保在将接收到的字符串用作字符串之前以空字符结尾。