【问题标题】:Comparing an input form client with a file on server side using strcmp使用 strcmp 将输入表单客户端与服务器端的文件进行比较
【发布时间】:2012-11-28 11:16:04
【问题描述】:

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


导师给了我一个 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);

}

【问题讨论】:

  • 这似乎是 C,而不是 C++,因为没有特定的 C++ 代码。如果是这种情况,请重新标记为 C。

标签: c network-programming


【解决方案1】:

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中的字符数。

【讨论】:

    猜你喜欢
    • 2011-06-21
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多