c++ - 为什么从服务器接收数据会出现段错误(No error in sending)?

标签 c++ regex sockets client-server

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

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

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

客户端:

#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,你需要先处理数据再发送。

关于c++ - 为什么从服务器接收数据会出现段错误(No error in sending)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24080626/

相关文章:

c++ - 仔细检查我的知识 : Unicode

c++ - 如何处理可以购买多少元素(int)和剩余多少钱(double)

c# - 替换字符串中的单个字符实例,保持多个字符不变

javascript正则表达式匹配以固定字符串开头的url

ruby - 在 ruby​​ 中发送和接收 TCP 数据

c++ - 为什么 C++ STL 如此大量地基于模板? (而不是在*接口(interface)*上)

c++ - 检查 Char 是否在范围内

java - 正则表达式替换 HTML 字符串中的样式属性

python - 通过UDP发送列表

线程中的 Java 套接字 - 无数据传输