Nowe posty

xx Problem ze sterownikami. (5)
2024-04-13, 21:25:16
xx Instalacja xfce4 (2)
2024-04-13, 16:20:17
xx Serie kompilacji bez instalacji dla “emerge” w Gentoo (2)
2024-04-08, 18:40:04
xx Plasma 6 w Neonie ssie trochę mniej ... (17)
2024-04-05, 10:03:46
xx Problem z Linux Lite po instalacji (3)
2024-04-03, 14:23:40
xx Jak właczyć num locka przy starcie systemu debian 12? (12)
2024-04-02, 17:43:54
xx Brak dźwieku w systemie. (5)
2024-04-02, 16:13:41
xx Dystrybucja pod HP Omen (7)
2024-03-29, 11:33:05
xx [Poradnik] Wyszukiwanie Sterowników (2)
2024-03-27, 21:08:23
xx Ile pingwinów? (1)
2024-03-27, 08:59:24

Autor Wątek: Miniserwer crashuje się na listen  (Przeczytany 3897 razy)

  • Gość
Miniserwer crashuje się na listen
« dnia: 2010-09-14, 15:29:22 »
Mój serwer (tak dla celów naukowych) crashuje się najprawdopodobniej na instrukcji listen. Nie mogę dojść dlaczego, sprawdzałem zgodność programu z tutorialem libc.

Gdzie może być błąd?

#include 
#include
#include
#include
#include
#include


int main()
{
    char server_version[] = "0.0.1";
    int server_port = 10000;
    char banner[] = "Xserver 0.0.1\\n";
    struct sockaddr_in server;
    struct sockaddr_in peer;
    int sock, sock_peer;
    int sockaddr_len;

    printf ("Xserver is going up\\n\\n");

    printf ("Xserver is going to open socket\\n");
    sock = socket (PF_INET, SOCK_STREAM, 0);

    if (sock == -1) {

        perror ("Xserver couldn't open socket\\n");
        printf ("Xserver is shut down\\n\\n");
        return 1;
        }

    memset (&server, 0, sizeof (server));
    server.sin_family = AF_INET;
    server.sin_port = htons(server_port);
    server.sin_addr.s_addr = htonl (INADDR_ANY);



    if (bind (sock, (struct sockaddr*)&server, sizeof (server)) == -1) {

        perror ("I couldn't bind Xserver to the port");
        return 2;

        }

    while (1) {

        if (listen (sock, 1) == -1) {

            perror ("I coulndn't listen to");
            return 3;

            }

        sockaddr_len = sizeof (server);

        if (accept (sock, (struct sockaddr*)&peer, &sockaddr_len) == -1) {

            perror ("I couldn't accept\\n");
            return 4;
            }

        printf ("I connected\\n");
        send (sock_peer, banner, strlen (banner), 0);

        break;

        }

    printf ("Xserver is going to close socket\\n");

    fclose (sock);

    printf ("Xserver is going down\\n\\n");
    return 0;
}

jk33

  • Gość
Miniserwer crashuje się na listen
« Odpowiedź #1 dnia: 2010-09-14, 15:57:04 »
1) warningi kompilatora są bardzo pomocne
2) opcje -Wall -pedantic kompilatora wyświetlają więcej (zazwyczaj) pomocnych warningów
3) strace Twoim przyjacielem
4) debugger Twoim przyjacielem

pozdrawiam, Janek

  • Gość
Miniserwer crashuje się na listen
« Odpowiedź #2 dnia: 2010-09-14, 20:26:53 »
Hmm... trochę pomogło. Na kompilatorze nic się nie wyświetla. Teraz jest problem z debuggerem, gdy próboje wysłać tekst:

Cytuj
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/tomasz/Dokumenty/c/xserver/bin/Debug/xserver

Breakpoint 1, main () at /home/tomasz/Dokumenty/c/xserver/main.c:11
11   {
(gdb) until 64
I connected
main () at /home/tomasz/Dokumenty/c/xserver/main.c:64
64           send (sock, banner, strlen (banner), 0);
(gdb) next

Program received signal SIGPIPE, Broken pipe.
0x0012d422 in __kernel_vsyscall ()
(gdb)
Nie wiem z jakiego powodu może być "złamany" potok.

Tak apropos dlaczego w pendatic mode nie może być komentarzy //?

#include 
#include
#include
#include
#include
#include
#include


int main()
{
    /* char server_version[] = "0.0.1"; */
    int server_port = 14000;
    char banner[] = "Xserver 0.0.1\\n";
    struct sockaddr_in server;
    struct sockaddr_in peer;
    int sock = -1;
    socklen_t sockaddr_len;
    /*
    printf ("Xserver is going up\\n\\n");

    printf ("Xserver is going to open socket\\n"); */
    sock = socket (PF_INET, SOCK_STREAM, 0);

    if (sock == -1) {

        perror ("Xserver couldn't open socket\\n");
        printf ("Xserver is shut down\\n\\n");
        return 1;
        }

    memset (&server, 0, sizeof (server));
    server.sin_family = AF_INET;
    server.sin_port = htons(server_port);
    server.sin_addr.s_addr = htonl (INADDR_ANY);



    if (bind (sock, (struct sockaddr*)&server, sizeof (server)) == -1) {

        perror ("I couldn't bind Xserver to the port");
        return 2;

        }

    while (1) {

        if (listen (sock, 1) == -1) {

            perror ("I coulndn't listen to");
            return 3;

            }

        sockaddr_len = (socklen_t)sizeof (server);

        if (accept (sock, (struct sockaddr*)&peer, &sockaddr_len) == -1) {

            perror ("I couldn't accept\\n");
            return 4;
            }

        printf ("I connected\\n");
        send (sock, banner, strlen (banner), 0);

        break;

        }

    printf ("Xserver is going to close socket\\n");

    close (sock);

    printf ("Xserver is going down\\n\\n");
    return 0;
}

jk33

  • Gość
Miniserwer crashuje się na listen
« Odpowiedź #3 dnia: 2010-09-14, 20:55:38 »
Zwróć uwagę, że na jednym porcie możesz obsługiwać więcej niż jedno połączenie przychodzące na raz.
W związku z tym funkcja accept działa trochę inaczej niż zakładasz w tym programie.
Na bazowym gnieździe (tym do nasłuchu) nie przesyłasz danych. Tylko akceptujesz nowe połączenia.
man 2 accept

Komentarze  // nie występowały jeszcze w standardzie ISO C89. Standard ten jest używany jako domyślny. W sumie nie wiem dlaczego. Możesz powiedzieć żeby kompilator używał innego standardu. Na przykład -std=c99.
więcej standardów obsługiwanych przez gcc -> man gcc