C++ 为什么从服务器接收数据时出现分段错误(发送时没有错误)?

C++ 为什么从服务器接收数据时出现分段错误(发送时没有错误)?,c++,regex,sockets,client-server,C++,Regex,Sockets,Client Server,这个错误毁了我的一天。这是我的第二个客户机-服务器程序。服务器是迭代类型。功能是1。服务器一直在运行。 2.客户端向服务器发送文件名。 3.服务器打开文件并处理其数据,并将信息发送回客户端。 但在客户端接收数据时,它会产生一个分段错误。甚至它也可以读取数据包内部,但只能读取“文件名”。 事实上,服务器正在打开一个文件并打开linux字典文件。它搜索任何拼写问题等。最后它有行号、单词和建议的单词。 我已经在服务器端的列表中进行了检查,列表没有错误。 这是我的代码摘要。如果有人能找到bug,我将不胜

这个错误毁了我的一天。这是我的第二个客户机-服务器程序。服务器是迭代类型。
功能是
1。服务器一直在运行。
2.客户端向服务器发送文件名。
3.服务器打开文件并处理其数据,并将信息发送回客户端。

但在客户端接收数据时,它会产生一个分段错误。甚至它也可以读取数据包内部,但只能读取“文件名”。
事实上,服务器正在打开一个文件并打开linux字典文件。它搜索任何拼写问题等。最后它有行号、单词和建议的单词。
我已经在服务器端的列表中进行了检查,列表没有错误。

这是我的代码摘要。如果有人能找到bug,我将不胜感激。我复制粘贴文件上除处理之外的所有代码。为长代码提前道歉

客户端:

#include <pthread.h>
#include <regex.h>
#include "wrappers.h"

struct SType{
  int Num;
  char Word[20];
  char sugg[20];
};


struct DataPktType
{
    list<SType> MyList;
    char filename[MAX_SIZE], message[MAX_SIZE];
    int numslaves;
};

int main(int argc, char **argv){
    int Sockfd;
    sockaddr_in ServAddr;
    char ServHost[] = "localhost";
    hostent *HostPtr;
    int Port = SERV_TCP_PORT;
    DataPktType DataPkt;
    DataPktType recDataPkt;
    string filename, tempstr;

    if (argc == 5){
        strcpy(ServHost, argv[1]);
        Port = atoi(argv[2]);
        filename = string(argv[3]);
        cout<<"filename= "<<filename<<endl;
        DataPkt.numslaves = atoi(argv[4]);
    } else{
        cout << "Usage: \"client <server address> <port> <textfile> <numThreads>\".\n" << endl;
        exit(1);
    }

    // Get the address of the host
    HostPtr = Gethostbyname(ServHost);

    if(HostPtr->h_addrtype !=  AF_INET)
    {
        perror("Unknown address type!");
        exit(1);
    }

    memset((char *) &ServAddr, 0, sizeof(ServAddr));
    ServAddr.sin_family = AF_INET;
    ServAddr.sin_addr.s_addr = ((in_addr*)HostPtr->h_addr_list[0])->s_addr;
    ServAddr.sin_port = htons(Port);

    // Open a TCP socket
    Sockfd = Socket(AF_INET, SOCK_STREAM, 0);

    // Connect to the server
    Connect(Sockfd, (sockaddr*)&ServAddr, sizeof(ServAddr));

    strcpy(DataPkt.filename, argv[3]);
    DataPkt.numslaves = 6;

    // Write and read a message to/from the server 
    write(Sockfd, (char*)&DataPkt, sizeof(DataPktType));
    read(Sockfd, (char*)&recDataPkt, sizeof(DataPktType));
    cout<<"here"<<endl;
    cout << setw(30) << left << "Filename:" << setw(20) << right << DataPkt.filename << endl;
    list<SType> MyList2;
    MyList2 = DataPkt.MyList;
    cout<<"size= "<<MyList2.size()<<endl;

    for (list<SType>::iterator it=MyList2.begin(); it!=MyList2.end(); it++)
        cout << ' ' << it->Num << ' ' << it->Word << endl;

    cout << "Finished\n";
    close(Sockfd);
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream.h>
#include <list>
#include <iomanip>
#include <pthread.h>
#include "wrappers.h"
#include<cstdlib>
#include<fstream>
#include<iostream>
#include<sstream>
#include <algorithm>

#define BUFSIZE 10
#define gNumThreads 6
using namespace std;


struct SType{
  int Num;
  char Word[20];
  char sugg[20];
};

struct DataPktType
{
    list<SType> MyList;
    char filename[MAX_SIZE], message[MAX_SIZE];
    int numslaves;
};



int main(int argc, char **argv){

    int Sockfd, NewSockfd, ClntLen, Port = SERV_TCP_PORT;
    sockaddr_in ClntAddr, ServAddr;
    DataPktType DataPkt;


    if (argc == 2){
        Port = atoi(argv[1]);
    }

    // Open a TCP socket (an Internet stream socket)
    Sockfd = Socket(AF_INET, SOCK_STREAM, 0); // socket() wrapper fn

    // Setup server for development
    setsockopt(Sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);

    // Bind the local address, so that the client can send to server
    memset((char*)&ServAddr, 0, sizeof(ServAddr));
    ServAddr.sin_family = AF_INET;
    ServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    ServAddr.sin_port = htons(Port);

    Bind(Sockfd, (sockaddr*) &ServAddr, sizeof(ServAddr));

    // Listen to the socket
    Listen(Sockfd, 5);

    for(;;)
    {
        // Wait for a connection from a client; this is an iterative server
        ClntLen = sizeof(ClntAddr);
        NewSockfd = Accept(Sockfd, (sockaddr*)&ClntAddr, &ClntLen);

        if(NewSockfd < 0)
        {
            perror("Can't bind to local address!");
        }

        // Read a message from the client
        read(NewSockfd, (char*)&DataPkt, sizeof(DataPktType));
        string line;
        ifstream myfile (DataPkt.filename);

        if (myfile.is_open())
        {
            --Here is some operation I deleted to make file shorter ---

                    if(!found)
                    {
                        /* Add suggestion to the list */
                        SType S;
                        S.Num = lineNo;
                        strcpy(S.Word, result);
                        strcpy(S.sugg, sugg);
                        MyList2.push_back(S);
                        cout<<lineNo<<"       "<<result<<"         "<<sugg<<endl;
                        cout<<"Not found in dictionary"<<endl;
                    }
                    else
                    {
                        cout<<"found: "<<result<<" in dictionary"<<endl;
                    }
                }
            }

            myfile.close();
            cout<<"List before write"<<endl;

            for (list<SType>::iterator it=MyList2.begin(); it!=MyList2.end(); it++)
                cout << ' ' << it->Num << ' ' << it->Word << endl;

            /*Send suggestion back to the client*/
            DataPktType retPack;

            retPack.MyList = MyList2;
            //DataPkt.filename
            strcpy(retPack.filename,"behzad");

            write(NewSockfd, (char*)&retPack, sizeof(DataPktType));
        }
        else {cout << "Unable to open file"; exit(1);}

    }
    close(NewSockfd);

    /* exit the program */
    return(0);
}
1       bernard         behead
Not found in dictionary
List before write
lineNo: 1 word: behzad sugg:  behead
$ ./client localhost 19431 carol.txt 6
filename= carol.txt
Finished
Segmentation Fault
客户端:

#include <pthread.h>
#include <regex.h>
#include "wrappers.h"

struct SType{
  int Num;
  char Word[20];
  char sugg[20];
};


struct DataPktType
{
    list<SType> MyList;
    char filename[MAX_SIZE], message[MAX_SIZE];
    int numslaves;
};

int main(int argc, char **argv){
    int Sockfd;
    sockaddr_in ServAddr;
    char ServHost[] = "localhost";
    hostent *HostPtr;
    int Port = SERV_TCP_PORT;
    DataPktType DataPkt;
    DataPktType recDataPkt;
    string filename, tempstr;

    if (argc == 5){
        strcpy(ServHost, argv[1]);
        Port = atoi(argv[2]);
        filename = string(argv[3]);
        cout<<"filename= "<<filename<<endl;
        DataPkt.numslaves = atoi(argv[4]);
    } else{
        cout << "Usage: \"client <server address> <port> <textfile> <numThreads>\".\n" << endl;
        exit(1);
    }

    // Get the address of the host
    HostPtr = Gethostbyname(ServHost);

    if(HostPtr->h_addrtype !=  AF_INET)
    {
        perror("Unknown address type!");
        exit(1);
    }

    memset((char *) &ServAddr, 0, sizeof(ServAddr));
    ServAddr.sin_family = AF_INET;
    ServAddr.sin_addr.s_addr = ((in_addr*)HostPtr->h_addr_list[0])->s_addr;
    ServAddr.sin_port = htons(Port);

    // Open a TCP socket
    Sockfd = Socket(AF_INET, SOCK_STREAM, 0);

    // Connect to the server
    Connect(Sockfd, (sockaddr*)&ServAddr, sizeof(ServAddr));

    strcpy(DataPkt.filename, argv[3]);
    DataPkt.numslaves = 6;

    // Write and read a message to/from the server 
    write(Sockfd, (char*)&DataPkt, sizeof(DataPktType));
    read(Sockfd, (char*)&recDataPkt, sizeof(DataPktType));
    cout<<"here"<<endl;
    cout << setw(30) << left << "Filename:" << setw(20) << right << DataPkt.filename << endl;
    list<SType> MyList2;
    MyList2 = DataPkt.MyList;
    cout<<"size= "<<MyList2.size()<<endl;

    for (list<SType>::iterator it=MyList2.begin(); it!=MyList2.end(); it++)
        cout << ' ' << it->Num << ' ' << it->Word << endl;

    cout << "Finished\n";
    close(Sockfd);
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream.h>
#include <list>
#include <iomanip>
#include <pthread.h>
#include "wrappers.h"
#include<cstdlib>
#include<fstream>
#include<iostream>
#include<sstream>
#include <algorithm>

#define BUFSIZE 10
#define gNumThreads 6
using namespace std;


struct SType{
  int Num;
  char Word[20];
  char sugg[20];
};

struct DataPktType
{
    list<SType> MyList;
    char filename[MAX_SIZE], message[MAX_SIZE];
    int numslaves;
};



int main(int argc, char **argv){

    int Sockfd, NewSockfd, ClntLen, Port = SERV_TCP_PORT;
    sockaddr_in ClntAddr, ServAddr;
    DataPktType DataPkt;


    if (argc == 2){
        Port = atoi(argv[1]);
    }

    // Open a TCP socket (an Internet stream socket)
    Sockfd = Socket(AF_INET, SOCK_STREAM, 0); // socket() wrapper fn

    // Setup server for development
    setsockopt(Sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);

    // Bind the local address, so that the client can send to server
    memset((char*)&ServAddr, 0, sizeof(ServAddr));
    ServAddr.sin_family = AF_INET;
    ServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    ServAddr.sin_port = htons(Port);

    Bind(Sockfd, (sockaddr*) &ServAddr, sizeof(ServAddr));

    // Listen to the socket
    Listen(Sockfd, 5);

    for(;;)
    {
        // Wait for a connection from a client; this is an iterative server
        ClntLen = sizeof(ClntAddr);
        NewSockfd = Accept(Sockfd, (sockaddr*)&ClntAddr, &ClntLen);

        if(NewSockfd < 0)
        {
            perror("Can't bind to local address!");
        }

        // Read a message from the client
        read(NewSockfd, (char*)&DataPkt, sizeof(DataPktType));
        string line;
        ifstream myfile (DataPkt.filename);

        if (myfile.is_open())
        {
            --Here is some operation I deleted to make file shorter ---

                    if(!found)
                    {
                        /* Add suggestion to the list */
                        SType S;
                        S.Num = lineNo;
                        strcpy(S.Word, result);
                        strcpy(S.sugg, sugg);
                        MyList2.push_back(S);
                        cout<<lineNo<<"       "<<result<<"         "<<sugg<<endl;
                        cout<<"Not found in dictionary"<<endl;
                    }
                    else
                    {
                        cout<<"found: "<<result<<" in dictionary"<<endl;
                    }
                }
            }

            myfile.close();
            cout<<"List before write"<<endl;

            for (list<SType>::iterator it=MyList2.begin(); it!=MyList2.end(); it++)
                cout << ' ' << it->Num << ' ' << it->Word << endl;

            /*Send suggestion back to the client*/
            DataPktType retPack;

            retPack.MyList = MyList2;
            //DataPkt.filename
            strcpy(retPack.filename,"behzad");

            write(NewSockfd, (char*)&retPack, sizeof(DataPktType));
        }
        else {cout << "Unable to open file"; exit(1);}

    }
    close(NewSockfd);

    /* exit the program */
    return(0);
}
1       bernard         behead
Not found in dictionary
List before write
lineNo: 1 word: behzad sugg:  behead
$ ./client localhost 19431 carol.txt 6
filename= carol.txt
Finished
Segmentation Fault

在发送或接收数据之前,您没有对数据进行任何类型的序列化

write(Sockfd,(char*)&DataPkt,sizeof(DataPktType));
读取(Sockfd,(char*)&recDataPkt,sizeof(DataPktType))


这部分是完全错误的,您的结构中有一个
std::list
,您需要先处理该数据,然后再发送它。

使用调试器在这里找到它崩溃的行。它在客户端崩溃:read(Sockfd,(char*)&recDataPkt,sizeof(DataPktType));确切地说,当它从服务器读取数据时,您不认为DataPktType应该在发送之前序列化为字节,在接收之后反序列化吗?若要尝试您的代码,请尝试发送和接收简单的字节数组,并检查它是否崩溃。如何序列化该列表?有什么建议吗?我如何序列化列表?有什么建议吗?列表的大小每次都是可变的!而且,当我将数据从客户端发送到服务器时,它也可以在不进行序列化的情况下工作!