2014-09-03 3 views
0

Я пытаюсь понять программирование сокета C для университетского экзамена. Я сделал этот простой пример:Программирование сокетов C: recv всегда сбой

socket_server.c

#include <sys/socket.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <arpa/inet.h> 

#define SA struct sockaddr 
#define MAX_MESS_LEN 16 

int main(){ 
    struct sockaddr_in my_addr, cl_addr; 
    int ret, len, sk, cn_sk; 
    char cl_ip[INET_ADDRSTRLEN + 1], msg[MAX_MESS_LEN + 1]; 

    sk = socket(AF_INET, SOCK_STREAM, 0); //creo socket TCP/IPv4 listener 
    printf("socket created! :)\n"); 
    memset(&my_addr, 0, sizeof(my_addr)); //azzero struttura my_addr 
    my_addr.sin_family = AF_INET; //famiglia protocolli IPv4 
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY); //in ascolto su qualsiasi interfaccia 
    my_addr.sin_port = htons(1234); //porta del socket 

    ret = bind(sk, (SA *) &my_addr, sizeof(my_addr)); //lego il socket alla struttura indirizzo 
    printf("socket binded! :)\n"); 
    ret = listen(sk, 10); //mi pongo in ascolto sul socket con massimo 10 richieste pendenti 
    printf("socket listening (on any interface with port 1234)! :)\n"); 
    len = sizeof(cl_addr); 
    printf("socket is going to wait for a request... zzzzZZZ\n"); 
    cn_sk = accept(sk, (SA *) &cl_addr, &len); //creo il socket connected per la richiesta in cima alla lista 
    printf("socket accepted request! :D\n"); 
    inet_ntop(AF_INET, &cl_addr.sin_addr, cl_ip, INET_ADDRSTRLEN); //converto indirizzo IPv4 cl_addr.sin_addr in stringa (cl_ip) 
    printf("IP client: %s\n", cl_ip); 

    ret = recv(sk, (void *) msg, MAX_MESS_LEN, MSG_WAITALL); //attendo la ricezione di tutti i caratteri della stringa inviata sul socket dal client 
    msg[MAX_MESS_LEN + 1] = '\0'; 
    printf("received data (%d bytes): %s\n", ret, msg); 
    if(ret == -1 || ret < MAX_MESS_LEN) 
     printf("recv ERROR! :(\n"); 

    close(sk); //chiudo il server 
} 

socket_client.c

#include <sys/socket.h> 
#include <stdio.h> 
#include <string.h> 
#include <arpa/inet.h> 
#define SA struct sockaddr 
#define MSG_LEN 17 

int main(){ 
    struct sockaddr_in srv_addr; 
    int ret, sk; 
    char msg[MSG_LEN]; 

    sk = socket(AF_INET, SOCK_STREAM, 0); 
    printf("Socket created! :)\n"); 
    memset(&srv_addr, 0, sizeof(srv_addr)); 
    srv_addr.sin_family = AF_INET; 
    srv_addr.sin_port = htons(1234); 
    ret = inet_pton(AF_INET, "192.168.1.132", &srv_addr.sin_addr); 

    printf("Trying to establish a connection with 192.168.1.132 on port 1234..."); 
    ret = connect(sk, (SA *) &srv_addr, sizeof(srv_addr)); //faccio una richiesta sul socket 
    if(ret != -1) printf("Connection established! :D\n"); 
    else printf(" connection error :(\n"); 

    strcpy(msg, "something to send"); //scrivo messaggio in una stringa 
    printf("sending message: %s\n", msg); 
    ret = send(sk, (void *) msg, strlen(msg), 0); //invio il messaggio sul socket 
    if(ret == -1 || ret < strlen(msg)) 
     printf("send ERROR! :(\n"); 

    close(sk); 
} 

И скомпилирован с:

gcc socket_client.c -o socket_client 
gcc socket_server.c -o socket_server 

Может быть, это глупый вопрос, но Функция recv на сервере всегда терпит неудачу, есть пример вывода:

Сервер:

socket created! :) 
socket binded! :) 
socket listening (on any interface with port 1234)! :) 
socket is going to wait for a request... zzzzZZZ 
socket accepted request! :D 
IP client: 192.168.1.132 
received data (-1 bytes): ���� 
recv ERROR! :(

Клиент:

Socket created! :) 
Trying to establish a connection with 192.168.1.132 on port 1234...Connection established! :D 
sending message: something to send 

В чем проблема? Я не понимаю! :(Я последовал шаг за шагом, руководство моего учителя.

Я работаю на arch linux 64 бит;) Благодарим за отзыв!

+3

Используйте 'perror' вместо' printf' для ошибок (или покажите 'errno' и' strerror (errno) 'как-то). Кроме того, скомпилируйте все предупреждения и информацию об отладке ('gcc -Wall -g'). Затем ** используйте отладчик ** ('gdb'). Внимательно прочитайте документацию [recv (2)] (http://man7.org/linux/man-pages/man2/recv.2.html). –

ответ

4
cn_sk = accept(sk, (SA *) &cl_addr, &len); //creo il socket connected per la richiesta in cima alla lista 
... 
ret = recv(sk, (void *) msg, MAX_MESS_LEN, MSG_WAITALL); //at 

Вы делаете не recv на подключенный сокет cn_sk к клиенту, но вместо этого на слушающего сокета sk. Если вы проверите errno, вы, вероятно, увидите ENOTCONN.

+0

Спасибо! я не верю, что я разместил вопрос для такой глупой ошибки, извините: P –

Смежные вопросы