我正试图在用户键入“L”时运行LIST命令,并显示可供下载的所有文件,但是当我运行它时,键入L后,程序会打印出“eetings”。我想我没有正确使用recv(),send()或fwrite()命令,我错过了什么?当我输入
时请进一步注意ncat 65.19.178.177 1234
在命令行中,它打印出“+ OK Greetings”,但当我在程序中输入“L”时,它会打印出“eetings”,所以我认为它是以某种方式从中获取的。
void menu()
{
printf("L) List files\n");
printf("D) Download a file\n");
printf("Q) Quit\n");
}
int main(int argc, char **argv)
{
struct sockaddr_in sa;
int sockfd;
sa.sin_family = AF_INET;
sa.sin_port = htons(1234);
inet_pton(AF_INET,"65.19.178.177", &sa.sin_addr);
sockfd = socket(PF_INET,SOCK_STREAM, IPPROTO_TCP);
if (sockfd == -1)
{
fprintf(stderr, "Can't create socket\n");
exit(3);
}
int res = connect(sockfd, (struct sockaddr *)&sa, sizeof(sa));
if (res == -1)
{
fprintf(stderr, "can't connect\n");
exit(2);
}
char buff[1000];
size_t rsize;
int resultcode;
//Get treeting from server. Expecting 220
rsize = recv(sockfd, buff, 1000, 0);
sscanf(buff, "%d", &resultcode);
if (buff[0]=='+')
{
printf("Success\n");
}
else
{
printf("Failed: Didn't get 220\n");
}
while(1)
{
menu();
char *choice = readline("Choice: ");
switch(choice[0])
{
case 'l':
case 'L':
//Handle L case
sprintf(buff, "LIST");
send(sockfd, buff, strlen(buff), 0);
while ((rsize = recv(sockfd, buff, 1000, 0)) > 0)
{
fwrite(buff, rsize, 1, stdout);
}
close(sockfd);
break;
答案 0 :(得分:1)
也许这就是正在发生的事情(我认为这就是@Martin James的意思):
在您的recv()
初始版本中,您不会检查rsize
的值,但如果buff[0] == '+'
之后感到满意。但是,您无法通过recv()
的一次通话确认您已收到完整的问候语,可能只是"+OK Gr"
,其余的仍在等待接收。
现在您发送命令,但在收到命令的结果之前,您将获得初始消息的其余部分,即"eetings"
你应该是这样的:
int received = 0;
int expected = strlen( "+OK Greetings" );
rsize = recv(sockfd, buff, 1000, 0);
if( resize <= 0 || buff[0] != '+' ) {
// do some error handling and exit
..
}
received = rsize;
while( received < expected ) {
rsize = recv(sockfd, buff+received, 1000-received, 0);
if( resize <= 0 ) {
// do some error handling and exit
..
}
received += rsize;
}
致电sscanf()
对我没有意义,因为根据您的问题,您不会收到数值。这是对的吗?
P.S .:
如果您无法访问“真正的调试器”,则可以随时在代码中添加一些printf()
语句,以查看发生的情况,如:
rsize = recv(sockfd, buff, 1000, 0);
printf( "recv() returns %d\n", rsize );