这是一项学校作业,我需要建立一个网络,客户端将输入发送到服务器,服务器将其与文件的内容进行比较,如果输入作为关键字存在于文件中,服务器将发回一条消息文件中的该项目。如果文件中不存在输入,服务器将发送一条未找到匹配的消息。
为了构建一个简单的网络,老师给了我一个 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/