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()入力文字列を null で終了する必要があります。fread()nullターミネータを追加せず(投稿されたコードに追加する余地もありません)、buffer初期化されません。許可されている場合は、ラインfgets()の代わりに、fread()またはstrtok()ラインを処理するために使用します。それ以外の場合は、 で 1 文字少なく読み取りfread()、 の最後の文字が でbufferあることを確認し'\0'ます。

strcmp()入力文字列を null で終了する必要がありrecv()、null ターミネータを追加せず、szBuff初期化されません。で 1 文字少なく読み取り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 に答える