Jak odesłać wiadomość do klienta?

0

Witam, probuje wykonuja komunikacje serwer - klient. Klient przesyla wiadomosc do serwera, wszystko działa poprawnie i wyswietla wiadomosc w terminalu, ale gdy probuje odeslac do klienta to w kliencie nic się nie dzieje w terminalu. W czym może być problem? Odsylam wiadomość na adres klienta ale klient z się zawiesza na recvfrom i nic nie otrzymuje.

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/un.h>
#include <netinet/udp.h>
#include <arpa/inet.h>

int main()
{
    unlink("tmp/unix1");
    int server = socket(AF_UNIX, SOCK_DGRAM, 0);

    // bind
    struct sockaddr_un address, client;
    address.sun_family = AF_UNIX; 
    strcpy(address.sun_path, "/tmp/unix12");

    char buff[1024] = "Message to server";
    char rcvMsg[1024];

    int len = sizeof(client);

    int bindc = bind(server, (struct sockaddr *)&address, sizeof(address));
    if(bindc==-1) {
        perror("bind");
        return -1;
    }

    while(1) {
    if(recvfrom(server, rcvMsg, 1024, 0, (struct sockaddr *) &client,
            &len) == -1){
         perror("recvfrom");
         return -1;
      }
        printf("from client: %s\n", rcvMsg);
        sendto(server, buff, 1024, 0, (struct sockaddr *)&client, sizeof(client));

    }

    close(server);

    return 0;
}

Klient:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/un.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
int main()
{
    int server = socket(AF_UNIX, SOCK_DGRAM, 0);

    // bind
    struct sockaddr_un address, client;
    address.sun_family = AF_UNIX; 
    strcpy(address.sun_path, "/tmp/unix12");

    char buff[1024] = "Message to server";
    char rcvMsg[1024];

    int len = sizeof(address);

    sendto(server, buff, 1024, 0, (struct sockaddr *)&address, sizeof(address));
    if(recvfrom(server, rcvMsg, 1024, 0, NULL, NULL) == -1) {
        perror("rcv");
        return -1;
    }
    printf("%s\n\n", rcvMsg);
    close(server);

    return 0;
}
0

Sporo do poprawy.

  1. Klientem musisz bindować osobny adres, żeby przekazać go serwerowi.
  2. Nie zerujesz struktur (chyba trzeba).
  3. Wysyłasz całe 1024 bajtów.
0

Poczytaj sobie manual do netcat-a - fragmenty dotyczące AF_UNIX i SOCK_DGRAM podpowiadają jak netcat to obsługuje.

A potem wywal to co napisałeś i użyj ZMQ ;)

1

Tak na szybko poprawiłem / dodałem - jeszcze dużo przy tym pracy, żeby było zgodne ze sztuką :P
Server:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/un.h>
#include <netinet/udp.h>
#include <arpa/inet.h>

int main()
{
    unlink("/tmp/unix12");
    int server = socket(AF_UNIX, SOCK_DGRAM, 0);

    // bind
    struct sockaddr_un address, client;
    memset(&address,0,sizeof(address));

    address.sun_family = AF_UNIX;
    strcpy(address.sun_path, "/tmp/unix12");

    const char *buff = "Message to server";
    char rcvMsg[1024];

    socklen_t len = sizeof(client);

    int bindc = bind(server, (struct sockaddr *)&address, sizeof(address));
    if(bindc==-1) {
        perror("bind");
        return -1;
    }

    while(1) {
        socklen_t addr_len = len;
        int bytes = recvfrom(server, rcvMsg, 1024, 0, (struct sockaddr *) &client,&addr_len);
        if(bytes == -1){
         perror("recvfrom");
         return -1;
        }
      rcvMsg[bytes] = '\0';
        printf("from client: %s\n", rcvMsg);
        sendto(server, buff, strlen(buff), 0, (struct sockaddr *)&client, addr_len);

    }

    close(server);

    return 0;
}

Client:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/un.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
int main()
{
    unlink("/tmp/unix13");
    int server = socket(AF_UNIX, SOCK_DGRAM, 0);

    // bind
    struct sockaddr_un address, client;

    memset(&client,0,sizeof(client));
    client.sun_family = AF_UNIX;
    strcpy(client.sun_path, "/tmp/unix13");

    const char *buff = "Message to server";
    char rcvMsg[1024];

    int bindc = bind(server, (struct sockaddr *)&client, sizeof(client));
    if(bindc==-1) {
        perror("bind");
        return -1;
    }
    memset(&address,0,sizeof(address));
    address.sun_family = AF_UNIX;
    strcpy(address.sun_path, "/tmp/unix12");

    sendto(server, buff, strlen(buff), 0, (struct sockaddr *)&address, sizeof(address));
    int bytes = recvfrom(server, rcvMsg, 1024, 0, NULL, NULL);
    if(bytes == -1) {
        perror("rcv");
        return -1;
    }
    rcvMsg[bytes] = '\0';
    printf("%s\n\n", rcvMsg);
    close(server);

    return 0;
}

1

Ja dam od siebie taką radę jakbyś gdzieś zobaczył SUN_LEN.
Nie używaj tego.

Lepiej zerować strukturę sun = {0}; na inicie;
i potem do bind przekazać sizeof sun
( oczywiście zakładam tu, że sun to nie pointer do struktury tylko struktura )

Dodatkowo sprawdzaj czy nazwa jaka nadajesz socketowi mieści się w sun_path bo to jest dość małe.

Możesz na kliencie nie bindować ( przy DATAGRAM pamiętaj!!! ) i serwer wtedy po prostu nie wie kto do niego gada.
Ta opcja może być wygodna jak zrobisz connect to używasz send na socket na kliencie i wszystko bangla.

Zawsze jakieś dodatkowe info, pozdrawiam!

1 użytkowników online, w tym zalogowanych: 0, gości: 1