分段错误通过TCP套接字发送结构

时间:2014-11-25 15:56:17

标签: c++ tcp

我正在写一个关于TCP Socket的简单程序。我要做的是从客户端向服务器发送1000个数据结构,但它显示分段错误....

这是我的服务器:

#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
using namespace std;

#pragma pack(1)
struct student
{
    int id;
    string name;
};

main()
{
   struct sockaddr_in socketInfo;
   socklen_t fromlen;
   int socketHandle;
   int portNumber = 8080;

   bzero(&socketInfo, sizeof(sockaddr_in));  // Clear structure memory

   // create socket

   if((socketHandle = socket(AF_INET, SOCK_STREAM, 0)) < 0)
   {
      close(socketHandle);
      exit(EXIT_FAILURE);
   }

   // Load system information into socket data structures

   socketInfo.sin_family = AF_INET;             //IPv4
   socketInfo.sin_addr.s_addr = htonl(INADDR_ANY); // Use any address available to the system
   socketInfo.sin_port = htons(portNumber);      // Set port number

   // Bind the socket to a local socket address

   if( bind(socketHandle, (struct sockaddr *) &socketInfo, sizeof(socketInfo)) < 0)
   {
      close(socketHandle);
      perror("bind");
      exit(EXIT_FAILURE);
   }

   listen(socketHandle, 1);

   int socketConnection;

   while(1)
   {
   cout<<"Waiting to connect ..."<<endl;
   if( (socketConnection = accept(socketHandle, NULL, NULL)) < 0)
   {
      cout<<"Fail!!"<<endl;
      exit(EXIT_FAILURE);
   }
   //close(socketHandle);

   int rc = 0;  // Actual number of bytes read
   struct student buf;

    while(1)
    {
        rc = recv(socketConnection, &buf, sizeof(struct student)+1, 0);
        cout<<"Recieve = "<<rc<<endl;
        if (rc<=0)
        break;

        cout<<buf.id<<endl;
        cout<<buf.name<<endl;
    }
    }
}

这是我的客户:

#include <iostream>
#include <sstream>
#include <string>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;

unsigned long inet_addr(const string a);

string int2str( int val )  // interger convert to string
{  
    ostringstream out;  
    out<<val;  
    return out.str();  
}

#pragma pack(1)
struct student
{
    int id;
    string name;
};

main()
{
   struct sockaddr_in remoteSocketInfo;
   struct hostent *hPtr;
   const char *remoteHost="localhost";
   int socketHandle;
   int portNumber = 8080;

   bzero(&remoteSocketInfo, sizeof(sockaddr_in));  // Clear structure memory

   if((hPtr = gethostbyname(remoteHost)) == NULL)
   {
      cerr << "System DNS name resolution not configured properly." << endl;
      cerr << "Error number: " << ECONNREFUSED << endl;
      exit(EXIT_FAILURE);
   }


   if((socketHandle = socket(AF_INET, SOCK_STREAM, 0)) < 0)
   {
      close(socketHandle);
      exit(EXIT_FAILURE);
   }

   // Load system information into socket data structures
   memcpy((char *)&remoteSocketInfo.sin_addr, hPtr->h_addr, hPtr->h_length);
   remoteSocketInfo.sin_family = AF_INET;
   remoteSocketInfo.sin_port = htons(portNumber);      // Set port number

   if(connect(socketHandle, (struct sockaddr *)&remoteSocketInfo, sizeof(sockaddr_in)) < 0)
   {
      close(socketHandle);
      exit(EXIT_FAILURE);
   }

   struct student buf[1000];

    for (int i=0; i<1000; i++)
    {
        buf[i].id = i+1;
        buf[i].name = "student_" + int2str(i) + "00";
        send(socketHandle, &buf[i], sizeof(struct student)+1, 0);
    }
}

结果:

Waiting to connect ...
Recieve = 13
1
Segmentation fault (core dumped)

1 个答案:

答案 0 :(得分:0)

这里的问题是struct student中的一个字段是std::string个对象。这不能像您一样直接通过电汇发送。

相反,要么将其更改为固定大小的字符数组,就像这样...

struct student
{
    int id;
    char name[100];
}

...并在那里写下你的名字。或者你必须以不同的方式通过电线发送它。