使用 strcmp 将输入表单客户端与服务器端的文件进行比较

标签 c network-programming

这是一项学校作业,我需要建立一个网络,客户端将输入发送到服务器,服务器将其与文件的内容进行比较,如果输入作为关键字存在于文件中,服务器将发回一条消息文件中的该项目。如果文件中不存在输入,服务器将发送一条未找到匹配的消息。


为了构建一个简单的网络,老师给了我一个 server.cpp 和 client.cpp 模板,我所要做的就是编写读取文件的部分,将输入与文件进行比较。到目前为止,如果我在客户端正确输入关键字,服务器程序就可以发回该项目。问题是,当我输入任何不是关键字的内容时,服务器端就会崩溃并报告我存在内存问题。


我对C++中的指针和内存不熟悉,所以我无法找出问题所在,因此我正在寻找出现此问题的原因和解决方法。这是那部分代码:

typedef struct {
int Number;
char* Subject_Code;
char* Subject_Title;
char* Timetable;
char* Instru_Name;
} time;

int parseNumber(char *line){
return atoi(line + 8);}
char *parseCode(char *line){
return line + 14;}
char *parseTitle(char *line){
return line + 15;}
char *parseTime(char *line){
return line + 11;}
char *parseInst(char *line){
return line + 13;}

int main(int argc, char **argv){
    char szBuff[1024];
int msg_len;
int addr_len;
struct sockaddr_in local, client_addr;

SOCKET sock, msg_sock;
WSADATA wsaData;

char *fileLocation ="data.txt";
FILE *file = fopen(fileLocation, "r");

if (!file)printf("%s\n",strerror(errno));
char buffer[1024];
time times[128];
int timeindex = 0;

    if (fread(buffer, 1, sizeof(buffer), file)){
        char *line = strtok(buffer, "\n");
        times[timeindex].Number = parseNumber(line);

        // 0 number, 1 code, 2 title, 3 table, 4 name
        int lineType = 1;
        while ((line= strtok(NULL, "\n"))){
            if(lineType == 5)
            {
                timeindex++;
                lineType = 0;
            }
            switch (lineType) {
            case 0:
                {
                    times[timeindex].Number = parseNumber(line);
                    break;
                }
            case 1:
                {
                    times[timeindex].Subject_Code = parseCode(line);
                    break;
                }
            case 2:
                { 
                    times[timeindex].Subject_Title = parseTitle(line);
                    break;
                }
            case 3:
                {
                    times[timeindex].Timetable = parseTime(line);
                    break;
                }
            case 4:
                {
                    times[timeindex].Instru_Name = parseInst(line);
                    break;
                }
            }
            lineType++; 
        }
    }

...
msg_len = recv(msg_sock, szBuff, sizeof(szBuff), 0);
...

if (msg_len > 0){       

    for (int c = 0; c <= timeindex; c++){
        if(strcmp(szBuff,times[c].Subject_Title)==0 || strcmp(szBuff,times[c].Subject_Code)==0 || strcmp(szBuff,times[c].Instru_Name)==0){
            msg_len = send(msg_sock, times[c].Timetable, sizeof(buffer), 0);
            break;
        }
    }




        msg_len = send(msg_sock, "No matchs were found.\n",20, 0);

}

最佳答案

strtok()要求其输入字符串以 null 结尾。 fread()不附加空终止符(在发布的代码中也没有任何空间)并且 buffer 未初始化。如果允许,请使用 fgets() 而不是 fread()strtok() 来处理行。否则,使用 fread() 少读取一个字符,并确保 buffer 中的最后一个字符是 '\0'

strcmp()要求其输入字符串以 null 终止,并且 recv() 不会附加 null 终止符,并且 szBuff 未初始化。使用recv()读取少一个字符,并确保szBuff中的最后一个字符是'\0'

如果times[c].Timetable指向的内存的字节数少于buffer,那么访问内存将是无效的:

msg_len = send(msg_sock, times[c].Timetable, sizeof(buffer), 0);

如果大小存在差异,则仅在times[c].Timetable中写入字符数。

关于使用 strcmp 将输入表单客户端与服务器端的文件进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13603779/

相关文章:

c - Keil uVision v.5.12.0.0 中的构建问题

c - 如何将数据插入到 MCU 编译的二进制文件中

c - 编译器中哪个函数负责接受main()的返回值

c - K&R book 1.5.1 文件复制

linux - packet mmap发送包格式

c - udp 套接字 - 绑定(bind)和连接成功,但发送不起作用

objective-c - 在 Objective-C 中编写网络发现工具

Java : download a web page using a URL from a specific server ip

c - 如何计算正在运行的线程数 (pthreads)?

c - 将多播地址添加到 Tap 驱动程序时的事件