Segmentation Fault in-Socket-Programmierung
Ich bin versucht, zu schreiben eine einfache server-client-Kommunikation Programm auf C. Aber ich bekomme immer wieder die Fehler auf der server-Seite, sobald ein client versucht, eine Verbindung zum server :
Segmentation Fault
Den Server-side-code ist :
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
void error(char *);
int main(int argc, char *argv[])
{
int sockfd, newsockfd, n, serv_size, cli_size, port_no, bindfd, readfd, writefd, listenfd;
char sbuffer[256];
char *p;
p = &sbuffer[0];
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2)
error("No port no. Specified!\n");
//creating sever side socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
error("Server side listening Socket could not be created!\n");
bzero((char *)&serv_addr, sizeof(serv_addr));
port_no = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port_no);
serv_addr.sin_addr.s_addr = INADDR_ANY;
//binding socket
bindfd = bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (bindfd == -1)
error("Failed to bind server side socket!\n");
//listening for incoming connections
listenfd = listen(sockfd, 5);
if (listenfd == -1)
error("Failed to lisen to incoming connections!\n");
serv_size = sizeof(serv_addr);
cli_size = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &serv_size);
if (newsockfd == -1)
error("Failed to accept connections from client!\n");
printf("Server received connections from %s \n", (char *)inet_ntoa(cli_addr.sin_addr));
while(1)
{
bzero(p, sizeof(sbuffer));
readfd = read(newsockfd, p, sizeof(sbuffer));
if (readfd == -1)
error("Sorry. Unable to read message from client!\n");
printf("Message Received: ");
puts(sbuffer);
bzero(p, sizeof(sbuffer));
printf("\nEnter Your Message for client: ");
gets(sbuffer);
writefd = write(newsockfd, p, sizeof(sbuffer));
if (writefd == -1)
error("Sorry. Message Could not be sent to client.\n");
printf("Congratulations! Message has been sent to client.\n");
}
return 0;
}
void error(char *msg)
{
perror(msg);
exit(1);
}
Den Client-seitigen code ist :
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
void error(char *);
int main(int argc, char *argv[])
{
int sockfd, newsockfd, port_no, n, connectfd, readfd, writefd;
char cbuffer[256];
char *ptr = &cbuffer[0];
struct sockaddr_in serv_addr;
struct hostent *he;
if (argc != 3)
error("Incomplete arguments!\n");
port_no = atoi(argv[2]);
he = gethostbyname(argv[1]);
if (he == NULL)
error("No Such Host!\n");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1)
error("Sorry. Socket could not be created!\n");
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port_no);
serv_addr.sin_addr = *((struct in_addr *)he->h_addr);
connectfd = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (connectfd == -1)
error("Sorry. Could not connect to server.\n");
while(1)
{
bzero(ptr, sizeof(cbuffer));
printf("\nEnter message for Server: \n");
gets(cbuffer);
writefd = write(sockfd, ptr, sizeof(cbuffer));
if (writefd == -1)
error("Sorry. Could not send message to Server.");
printf("Congratulations! Server Successfully Received your message.\n");
bzero(ptr, sizeof(cbuffer));
readfd = read(sockfd, ptr, sizeof(cbuffer));
if (readfd == -1)
error("Sorry. Message from server could not be read.\n");
printf("Message Received: ");
puts(cbuffer);
}
return 0;
}
void error(char *msg)
{
perror(msg);
exit(1);
}
Dies ist meine compile-Zeit Warnung beim kompilieren serv.c:
cc -o s serv.c
serv.c: In function ‘main’:
serv.c:47:52: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
P. S. : ich war mit Ubuntu 12.04, wo ich schrieb tatsächlich diese Programme erfolgreich umgesetzt, die Programme. Aber ich habe vor kurzem migriert zu Linux Mint 13 Cinnamon. Ich kompiliert die Programme. Vielleicht sind Sie erfolgreich ausgeführt, auf Mint zu. Aber nun scheint sich gefangen zu haben dieser Fehler irgendwie.
- Bitte versuchen Sie nicht zu vergeuden, andere Zeit. Im moment code ist nicht richtig eingerückt und macht das Lesen schwierig. Auch in meiner Erfahrung, Einrücken von code ist richtig gute Technik sowieso und tun es sich selbst aussetzen können, Sie Ihr problem suchen zu lösen. Für eigene Hilfe, drucken Sie auch errno-Wert nach dem read() und solche Anrufe. Es sind Werte wie EAGAIN die nicht den Fehler eigentlich. Und danach, wie jemand schon angedeutet, unten, bekommen, debugger und finden Sie heraus, wo es abgestürzt und warum.
- cs.cmu.edu/~gilpin/tutorial
- Versuchen Sie, um den Einsatz neuer Ansatz mit getaddrinfo() statt Füllung serv_addr struct manuell. Ein weiterer Vorteil ist, dass getaddrinfo() ist die Unterstützung von IPv6.
- Also, was ist mit Zeile 47 in
serv.c
bitte? serv_size
undcli_size
ist der Typsocklen_t
. Sehenman bind
,man accept
, undman connect
.- Nur compilieren mit -g-flag und verwenden valgrind. Dies wird wahrscheinlich Hilfe, die Sie identifizieren Sie die Ursache des Problems.
- Ich bin traurig über den Gedankenstrich. Ich bin neu auf stackoverflow und seine meine erste Frage. Ich mache Gedankenstrich mein code. Alles messedd beim einfügen in hier. Sorry, ich war unvorsichtig genug, um nicht mit cross-check.
- Beachten Sie, dass wenn Sie Emacs, können Sie die 4 space Einrückung notwendig für die Buchung hier, um alle Linien mit der Tastenkombination
C-x,r,t
. Andere Editoren können das gleiche Angebot.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie eine 64-bit-system ist, wird Ihr Anruf;
...kann brechen. Da hast du nicht im Lieferumfang enthalten
<arpa/inet.h>
Sie nicht über eine definition für inet_ntoa. Das wird der compiler annehmen, dass es gibt einint
. Daint
ist nicht unbedingt 64-bit (eigentlich die meisten Maschinen scheint es nicht zu sein), ist es nicht lange genug, um die char-Zeiger zurückgegeben wird, so dass Ihr printf stürzt mit eine ungültige Zeichenfolge. Dies geschieht auf (zum Beispiel) 64-bit MacOS X.Einfach nur setzen
#include <arpa/inet.h>
unter die includes die in dem server würde das problem beheben.Sollten Sie auch nicht vergessen, dass der Unterschied zwischen
int
undsocklen_t
und zu beheben das Problem der Vermischungcli_size
undserv_size
Lesen der bereits vorhandenen Kommentare und Antworten mehr.#include <arpa/inet.h>
behoben, der Warnung und der Segmentation Fault auf einmal.socklen_t
eingeführt wurde, als einen separaten Datentyp für alle Fälle abdecken kann.Ich würde sagen, das Problem ist das fehlende Vorbild für
inet_ntoa()
.Dieses let ' s der compiler davon ausgehen, es gibt
int
.Dass die folgende Zeile zum Absturz der app:
Dass enthalten
<arpa/inet.h>
den folgenden code whould haben kompiliert ohne Warnung auch mit-Wall
.