2017-12-04 8 views
2

Ich versuche, eine Client-Server-Anwendung in Linux zu erstellen. Der Server sendet das Objekt an den Client, aber der Client schreibt den Segmentierungsfehler. Hier ist der Code. Snake ist Klasse, wo zweidimensionales Array ist.Segmentierungsfehler - Objekt über Server an Client senden

Client Nachricht senden "P" und Server erstellt Objekt, das an den Client gesendet wird.

Server-Seite:

int main(int argc, char *argv[]) 
    { 

int sockfd, newsockfd; 
socklen_t cli_len; 
struct sockaddr_in serv_addr, cli_addr; 
int n; 
char buffer[256]; 


if (argc < 2) 
{ 
    fprintf(stderr,"usage %s port\n", argv[0]); 
    return 1; 
} 

bzero((char*)&serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
serv_addr.sin_addr.s_addr = INADDR_ANY; 
serv_addr.sin_port = htons(atoi(argv[1])); 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) 
{ 
    perror("Error creating socket"); 
    return 1; 
} 

if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) 
{ 
    perror("Error binding socket address"); 
    return 2; 
} 
while(sockfd){ 
listen(sockfd, 5); 
cli_len = sizeof(cli_addr); 

newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len); 

if (newsockfd < 0) 
{ 
    perror("ERROR on accept"); 
    return 3; 
} 

bzero(buffer,256); 
n = read(newsockfd, buffer, 255); 
if (n < 0) 
{ 
    perror("Error reading from socket"); 
    return 4; 
} 


// if client send 'p' 
if(*buffer == 'p' ){ 
     Snake *snake = new Snake(); 

    send(newsockfd,reinterpret_cast<const char*>(&snake), sizeof(snake),0); 
    } 
} 



//printf("Here is the message: %s\n", buffer); 

const char* msg = "I got your message"; 
n = write(newsockfd, msg, strlen(msg)+1); 
if (n < 0) 
{ 
    perror("Error writing to socket"); 
    return 5; 
} 

close(newsockfd); 

close(sockfd); 

} 

Client-Seite:

int main(int argc, char *argv[]) 
{ 
int sockfd = 0,newsockfd, n; 
struct sockaddr_in serv_addr; 
struct hostent* server; 
socklen_t cli_len, serv_len; 

char buffer[999999]; 
struct sockaddr_in cli_addr; 

if (argc < 3) 
{ 
    fprintf(stderr,"usage %s hostname port\n", argv[0]); 
    return 1; 
} 

server = gethostbyname(argv[1]); 
if (server == NULL) 
{ 
    fprintf(stderr, "Error, no such host\n"); 
    return 2; 
} 

bzero((char*)&serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
bcopy(
    (char*)server->h_addr, 
    (char*)&serv_addr.sin_addr.s_addr, 
    server->h_length 
); 
serv_addr.sin_port = htons(atoi(argv[2])); 
//while(sockfd >= 0){ 
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) 
{ 
    perror("Error creating socket"); 
    return 3; 
} 

if(connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) 
{ 
    perror("Error connecting to socket"); 
    return 4; 
} 

printf("Please enter a message: "); 
bzero(buffer,256); 
fgets(buffer, 255, stdin); 

n = write(sockfd, buffer, strlen(buffer)); 

if (n < 0) 
{ 
    perror("Error writing to socket"); 
    return 5; 
} 

Snake *snake ; 

recv(sockfd,reinterpret_cast<char*>(&snake), sizeof(snake),0); 

if (n < 0) 
{ 
    perror("Error reading from socket"); 
    return 6; 
} 

printf("%s\n",buffer); 

close(sockfd); 
close(newsockfd); 
return 0; 
} 

Vielen Dank für Ihre Antworten.

+0

Wenn Sie eine Adresse eines Objekts im Serverprozess an den Clientprozess senden, ist diese Adresse im Clientprozess nicht gültig. Jeder Prozess hat seinen eigenen geschützten Speicher. (Dies wird sowohl von Linux als auch von jedem anderen modernen Betriebssystem gewährt.) Die Ausnahme wäre, wenn Server und Client denselben _shared memory_ verwenden würden. – Scheff

+2

'char Puffer [999999];' das ist eine schlechte Idee, diese Struktur auf Heap oder als globales Array zu erstellen. – rafix07

+0

Bitte überarbeiten Sie das Code-Beispiel, das Sie in dieser Frage gepostet haben. Wie es derzeit aussieht, machen es uns die Formatierung und der Umfang schwer, Ihnen zu helfen. Hier ist eine [großartige Ressource] (http://stackoverflow.com/help/mcve), um dich damit anzufangen. -1, nimm es nicht falsch. Eine Down-Abstimmung zeigt, wie wir hier auf ein inhaltliches Problem hinweisen. Verbessere deine Formatierung und Codebeispiele und ich (oder jemand) werde es gerne rückgängig machen. Viel Glück mit deinem Code! – Clijsters

Antwort

4

Auf der Clientseite

Snake *snake ; 

recv(sockfd,reinterpret_cast<char*>(&snake), sizeof(snake),0); 

versucht, in eine Schlange zu lesen, aber Sie haben nicht erstellt. Der nicht initialisierte Zeiger gibt also den Segmentierungsfehler an.

Außerdem ist sizeof(snake) die Größe eines Zeigers (wie 4 Bytes), nicht die Größe des Objekts, auf das verwiesen wird. Dies geschieht sowohl auf dem Server als auch auf dem Client.

+0

Ich bin mir nicht sicher, ob das Senden des Zeigers ("Schlange") tatsächlich beabsichtigt oder zufällig war. OP verwendet explizit '& Schlange', obwohl' Schlange' bereits ein Zeiger ist. "Der Server erstellt ein Objekt, das an den Client gesendet wird." könnte entweder bedeuten oder ... – Scheff

+0

Stimmt, ich habe das '&' nicht bemerkt. Es könnte auch andere Probleme geben, aber das ist mir aufgefallen. –

+0

Dies macht jedoch Ihre Antwort nicht ungültig. ;-) – Scheff

Verwandte Themen