TCP服务器上的分段错误

时间:2019-02-03 23:29:40

标签: tcp server runtime-error

我已经用C ++开发了一个服务器和一个与其连接的客户端。

两者都在装有Linux的PC上运行。

当我们运行服务器并且客户端连接到它时, 服务器上的分段错误,特别是在网上:     sClient =(((结构ThreadArgs *)threadArgs)-> sClient;

随附的是服务器的源代码:

ServerTCP.h:

#ifndef _SERVER_TCP_
#define _SERVER_TCP_
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>


struct ThreadArgs
{
  int sClient;
};

typedef void* (*THREAD_FUNC_PTR)(void *);

class ServerTCP
{
private:
  int sPort;

public:
  ServerTCP(unsigned int port);
  void *ThreadMain(void *threadArgs);
  void waitConnections();
};

#endif

ServerTCP.cpp:

#include "ServerTCP.h"

#define MAX_DATA_LENGTH 65000


ServerTCP::ServerTCP (unsigned int port)
{
  sPort = port;
}



void* ServerTCP::ThreadMain(void *threadArgs)
{
  int sClient;

  int ret;
  char data_in[MAX_DATA_LENGTH];

  pthread_detach(pthread_self() ) ;

  //>>> SIGSEGV, Segmentation fault
  sClient = ((struct ThreadArgs *) threadArgs) -> sClient;

  free(threadArgs);
  ret = 1;
  while (ret != 0)
  {
    ret = recv(sClient, data_in, MAX_DATA_LENGTH, 0);
    if (ret < 0)
    {
      printf("Error: Call to recv(sClient, frame_in, sizeof(frame_in), 0); has failed.\n");
      exit(1);
    }
  }

  close(sClient);
  return NULL;
}



void ServerTCP::waitConnections()
{
  int ret;
  unsigned int iPort, iAddrLen;
  int sListen, sClient;
  struct sockaddr_in addr, remote_addr;
  pthread_t threadID;
  struct ThreadArgs *threadArgs;


  sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  if (sListen < 0)
  {
    printf("Error: Call to socket(AF_INET, SOCK_STREAM, IPPROTO_IP); has failed.\n");
    exit(1);
  }

  iPort = sPort;

  addr.sin_family = AF_INET;
  addr.sin_port = htons(iPort);
  addr.sin_addr.s_addr = htonl(INADDR_ANY);


  sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  if (sListen < 0)
  {
    printf("Error: Call to socket(AF_INET, SOCK_STREAM, IPPROTO_IP); has failed.\n");
    exit(1);
  }

  addr.sin_family = AF_INET;
  addr.sin_port = htons(iPort);
  addr.sin_addr.s_addr = htonl(INADDR_ANY);
  ret = bind(sListen, (struct sockaddr *) &addr, sizeof(addr));

  if(ret < 0)
  {
    printf("Error: Call to bind(sListen, (struct sockaddr *) &addr, sizeof(addr)); has failed.\n");
    exit(1);
  }

  ret = listen(sListen, 10);
  if(ret < 0)
  {
    printf("Error: Call to listen(sListen, 10); has failed.\n");
    exit(1);
  }

  for(;;)
  {
    printf("Waiting for connection from a client...\n");

    iAddrLen = sizeof(remote_addr);

    sClient = accept(sListen, (struct sockaddr *) &remote_addr, &iAddrLen);
    if(sClient < 0)
    {
      printf("Error: Call to accept(sListen, (struct sockaddr *) remote_addr, sizeof(remote_addr)); has failed.\n");
      exit(1);
    }

    printf("%s has connected.\n\n", inet_ntoa(remote_addr.sin_addr));

    if ((threadArgs = (struct ThreadArgs *) malloc(sizeof(struct ThreadArgs))) == NULL)
    {
      printf("Error: malloc() for threadArgs has failed.\n");
      exit(1);
    }

    threadArgs -> sClient = sClient;
    printf ("sClient = %d, threadArgs -> sClient = %d\n", sClient, threadArgs -> sClient);

    if (pthread_create(&threadID, NULL, (THREAD_FUNC_PTR)&ServerTCP::ThreadMain, (void *)threadArgs) != 0)
    {
      printf("Error: pthread_create() has failed.\n");
      exit(1);
    }
  }
}



int main(int argc, const char* argv[])
{
  ServerTCP serverTCP(5772);

  serverTCP.waitConnections();

  return 0;
}

我正在作为C ++类开发的TCP服务器基于完美运行的C客户端服务器应用程序。

服务器的C ++类旨在作为用C编写的服务器的副本,并且可以正常工作。

我附上用C语言编写的客户端和服务器的代码。

当我在C ++中测试服务器时,我也使用用C编写的客户端。

如果C服务器工作正常,但是C ++服务器出现分段错误,那么我将服务器代码从C迁移到C ++时,我在做什么错?

client.c :(工作正常)

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


#define MAX_FRAME_LENGTH    65000


int main()
{
  struct hostent *host;

  char data_out[MAX_FRAME_LENGTH];
  int ret, aux;

  char serverAddress[64];
  int iPort;

  int s;
  struct sockaddr_in addr;

  char keys[50];

  strcpy (serverAddress, "localhost");
  iPort = 5772;

  s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  if(s < 0)
  {
    printf("Error: Call to socket has failed.\n");
    exit(1);
  }

  addr.sin_family = AF_INET;
  addr.sin_port = htons(iPort);
  addr.sin_addr.s_addr = inet_addr(serverAddress);

  if(addr.sin_addr.s_addr == INADDR_NONE)
  {
    host = NULL;
    host = gethostbyname(serverAddress);

    if(host == NULL)
    {
      printf("Error\nUnknown host: %s\n", serverAddress);
      exit(1);
    }
    memcpy(&addr.sin_addr, host->h_addr_list[0], host->h_length);
  }

  ret = connect(s, (struct sockaddr *) &addr, sizeof(addr));
  if (ret < 0)
  {
    printf("Error: Call to connect(s, (SOCKADDR) addr, sizeof(addr)); has failed.\n");
    exit(1);
  }

  printf("Client has connected to %s:%d\n",serverAddress, iPort);
  printf ("Please, press any key to send data to the Server. Press 'e' to finish.\n\n");

  do
  {
    for (aux=0; aux<20; aux++)
      data_out[aux] = aux;

    ret = send(s, data_out, 20, 0);
    if (ret < 0)
    {
      printf("Error: Call to send has failed.");
      exit(1);
    }
    else if (ret != 20)
      printf ("ERROR sending data: Wrong length of data.\n");

    aux = scanf ("%s", keys);
  }
  while ((strcmp (keys, "e") != 0) && (strcmp(keys, "E") != 0));

  close(s);
  return 0;
}

serverTCP.c:(C版本。它工作正常)

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>



#define MAX_DATA_LENGTH 65000



struct ThreadArgs
   {
   int sClient;
   };

void *ThreadMain(void *arg);    /* Main program of a thread */



int main()
{
  int ret;
  unsigned int iPort, iAddrLen;
  int sListen, sClient;
  struct sockaddr_in addr, remote_addr;
  pthread_t threadID;
  struct ThreadArgs *threadArgs;

  iPort = 5772;

  sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  if (sListen < 0)
  {
    printf("Error: Call to socket(AF_INET, SOCK_STREAM, IPPROTO_IP); has failed.\n");
    exit(1);
  }

  addr.sin_family = AF_INET;
  addr.sin_port = htons(iPort);
  addr.sin_addr.s_addr = htonl(INADDR_ANY);

  ret = bind(sListen, (struct sockaddr *) &addr, sizeof(addr));
  if(ret < 0)
  {
    printf("Error: Call to bind(sListen, (struct sockaddr *) &addr, sizeof(addr)); has failed.\n");
    exit(1);
  }

  ret = listen(sListen, 10);
  if(ret < 0)
  {
    printf("Error: Call to listen(sListen, 10); has failed.\n");
    exit(1);
  }

  for(;;)
  {
    printf("Waiting for connection from a client...\n");

    iAddrLen = sizeof(remote_addr);

    sClient = accept(sListen, (struct sockaddr *) &remote_addr, &iAddrLen);
    if(sClient < 0)
    {
      printf("Error: Call to accept(sListen, (struct sockaddr *) remote_addr, sizeof(remote_addr)); has failed.\n");
      exit(1);
    }

    printf("%s has connected.\n\n", inet_ntoa(remote_addr.sin_addr));

   if ((threadArgs = (struct ThreadArgs *) malloc(sizeof(struct ThreadArgs))) == NULL)
    {
      printf("Error: malloc() for threadArgs has failed.\n");
      exit(1);
    }

    threadArgs -> sClient = sClient;

    if (pthread_create(&threadID, NULL, ThreadMain, (void *)threadArgs) != 0)
    {
      printf("Error: pthread_create() has failed.\n");
      exit(1);
    }
  }
}



void *ThreadMain(void *threadArgs)
{
  int sClient;
  int ret;
  char data_in[MAX_DATA_LENGTH];

  pthread_detach(pthread_self() ) ;

  sClient = ((struct ThreadArgs *) threadArgs) -> sClient;
  free(threadArgs);

  ret = 1;
  while (ret != 0)
  {
    printf("Waiting to receive client data.\n");

    ret = recv(sClient, data_in, MAX_DATA_LENGTH, 0);
    if (ret < 0)
    {
      printf("Error: Call to recv(sClient, frame_in, sizeof(frame_in), 0); has failed.\n");
     exit(1);
    }

    printf("Received data from client %d\n\n", sClient);
  }

  close(sClient);
  return NULL;
}

0 个答案:

没有答案