Я разработал сервер на C ++ и клиент, который подключается к нему.
Оба работают на ПК с Linux.
Когда мы запускаем сервер, а клиентк нему подключена ошибка сегментации на сервере, в частности, по строке: sClient = ((struct 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;
}
Сервер TCP, который я разрабатываю как класс C ++, основан на клиенте 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;
}