2

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


为了搭建一个简单的网络,导师给了我一个 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);

}

4

1 回答 1

2

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

strcmp()要求其输入字符串为空终止,recv()并且不附加空终止符szBuff且未初始化。用 少读一个字符,recv()并确保最后一个字符szBuff'\0'

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

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

times[c].Timetable仅在大小不同的情况下写入字符数。

于 2012-11-28T11:20:51.207 回答