strcmp的坑

strcmp的坑

下面的程序是通过对输入进行判断,来决定输出内容的。

# include
#include
int main(){
    printf("请输入: ");
    char buf[1024];
	//这里想通过判断输入是否是quit来决定是否完成阅读
    if (fgets(buf, sizeof(buf), stdin) != NULL && (strcmp(buf, "quit"))){
        printf("欢迎阅读本文章\n");
        for (int i = 0;i < 1024;i++){
        	//打印每个字符的内容
            printf("%d ",buf[i]);
        }
    }
    else{
        printf("您已经阅读完成本文了,点一下关注哈\n");
    }
    printf("\n");
}

但是当输入quit的时候,没有走else流程。运行结果居然是是第一个输出。通过打印出来的buf中的字符来看,发现多了个10,因此buf比"quit"要大,也就是strcmp的返回结果是10,为真,所以会走if的流程。
strcmp的坑_第1张图片

实战抓包

重写客户端

通过上面的分析,可以看出,在这篇文章中,想通过输入quit来关闭socket的实现是有问题的。可以通过另一个函数完美解决这个问题-strncmp。

原型:strcmp(str1,str2);
功能:比较两个字符串,如果两个字符串相等,则返回0;若str1大于str2(对于大于的理解,是指从两个字符串的第一个字符开始比较,若两个字符相同,则继续比较,若发现两个字符不相等,且str1中该字符的ASCII码大于str2中的,则表示str1大于str2),返回一个正数(这个正数不一定是1);若str1小于str2,返回一个负数(不一定是-1);若字符串str1的长度大于str2,且str2的字符与str1前面的字符相同,则也相对于str1大于str2处理
原型2:strncmp(str1,str2,n);
功能2:比较两个字符串的前n个字符

重新写下客户端的代码

/*************************************************************************

> File Name: client.c

> Author: 无情剑客

> Mail: [email protected]

> Created Time: 2020年07月01日 星期三 21时44分37秒

 ************************************************************************/

#include

#include

#include

#include

#include

#include

#include

#define PORT 6666

#define MAXDATASIZE 2048

int main(int argc, char *argv[])

{

    if(argc != 2)

    {

        fprintf(stderr, "请您输入ip地址!\n");

        exit(1);

    }

    int sockfd;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    const char *server_ip = argv[1]; //从命令行获取输入的ip地址,此处没有对ip地址进行检验

    struct sockaddr_in serveraddr;

    bzero(&serveraddr, sizeof(serveraddr));

    serveraddr.sin_family = AF_INET;

    serveraddr.sin_port = htons(PORT);

    inet_pton(AF_INET, server_ip, &serveraddr.sin_addr);

    connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));

    printf("=====================服务器链接成功=====================\n");

    char buf[MAXDATASIZE];

    memset(buf, 0 ,  sizeof(buf));

    printf("请输入: ");
	//判断输入的内容是否是quit,如果输入quit,则关闭连接
    while(fgets(buf, sizeof(buf), stdin) != NULL && (strncmp(buf, "quit", 4)))

    {

        send(sockfd, buf, sizeof(buf), 0);

        memset(buf, 0, sizeof(buf));

        recv(sockfd, buf, sizeof(buf), 0);

        printf("服务器说: ");

        fputs(buf, stdout);

        memset(buf, 0, sizeof(buf));

        printf("请输入: ");

    }

    printf("客户端将要被关闭,下次再见\n");

    close(sockfd);

    return 0;

}

服务器端代码可参考这篇文章。

完整抓包

开启wireshark,来进行一次完整的抓包。

strcmp的坑_第2张图片因为服务iqi地址是127.0.0.1。本地环回地址,所以使用Loopback:lo接口。如果不是本地的服务器,需要选择相应的网卡接口。下面两个图展示了TCP的三次握手和四次挥手。
strcmp的坑_第3张图片
在这里插入图片描述

公众号

strcmp的坑_第4张图片

你可能感兴趣的:(漏洞,网络与安全,Android平台)