这个错误摧毁了我的一天。这是我的第二个客户端服务器程序。服务器是迭代类型。
功能是1.服务器一直在运行。
2.Client向服务器发送文件名
3.Server打开文件并处理其数据并将信息发送回客户端
但是在客户端接收数据时会产生分段错误。即使它可以读取数据包内部,但只有" filename"。
实际上服务器正在打开一个文件并打开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
答案 0 :(得分:1)
在发送或接收之前,您没有对数据进行任何类型的序列化。
write(Sockfd, (char*)&DataPkt, sizeof(DataPktType));
read(Sockfd, (char*)&recDataPkt, sizeof(DataPktType));
那部分是完全错误的,你的结构中有std::list
,你需要先发送数据然后再发送它。