Сетевое программирование на C (данные не передаются от клиента к серверу с помощью send())

У меня есть два файла: клиент и сервер, я хочу отправить значение переменной (выбор) с клиента на сервер, но значение не отправляется, и я понятия не имею, в чем проблема

это мой код для клиента

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sys/types.h>
    #include<netinet/in.h>
    #include<sys/socket.h>
    #include<netdb.h>
    #include<arpa/inet.h>
    #include<fcntl.h>

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

        char buf;
        int clientSocket, cnnt,fileDiscriptor,sizeInByte=0 , size=0 , serverSocket,choice=2 ;
        struct sockaddr_in serverInfo;

        if(argc != 3)
        {
            printf("Few arguments\nUsage : ./client <ip> <port>\n");
            exit(1);    
        }

        memset(&serverInfo,0,sizeof(serverInfo));   

        serverInfo.sin_family = AF_INET;
        inet_aton(argv[1],&serverInfo.sin_addr.s_addr);
        serverInfo.sin_port = htons(atoi(argv[2]));
        clientSocket = socket(AF_INET,SOCK_STREAM,0);
        if(clientSocket < 0)
        {
            printf("Could not create client socket\n");
            exit(1);
        }

        cnnt = connect(clientSocket,(struct sockaddr *)&serverInfo,sizeof(serverInfo));
        if(cnnt < 0)
        {   
            printf("Could not create connection to the server\n");   
            exit(1);    
        }
        recv(clientSocket , &serverSocket , sizeof(int) , 0);
        send(serverSocket , &choice , sizeof(int),0);
        close(clientSocket);
        return 0;

    }

и это мой код для сервера

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sys/types.h>
    #include<netinet/in.h>
    #include<sys/socket.h>
    #include<netdb.h>
    #include<arpa/inet.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include <sys/wait.h>


    int main(int argc , char *argv[])
    {   
        int choice;
        int serverSocket, bnd, lstn , clientSize, connectionFd;
        struct sockaddr_in serverInfo, clientInfo  ;

        if(argc != 2)
        {   
            printf("Few arguments\nUsage : ./server <port>\n");
            exit(1);    
        }   

        memset(&serverInfo , 0 , sizeof(serverInfo));
        memset(&clientInfo , 0 , sizeof(clientInfo));   

        serverInfo.sin_family = AF_INET;
        serverInfo.sin_port = htons(atoi(argv[1]));
        serverInfo.sin_addr.s_addr = INADDR_ANY;
        serverSocket = socket(AF_INET,SOCK_STREAM,0);
        if(serverSocket < 0)
        {
            printf("Could not create server socket\n");
            exit(1);    
        }

        bnd = bind(serverSocket , (struct sockaddr *)&serverInfo , sizeof(serverInfo));
        if(bnd < 0)
        {
            printf("Could not bind\n");
            exit(1);    
        }

        lstn = listen(serverSocket , 1);
        if(lstn < 0)
        {
            printf("Could not listen on server socket\n");
            exit(1);    
        }
        clientSize = sizeof(clientInfo);
        while(1)
        {
            connectionFd =  accept(serverSocket , (struct sockaddr *)&clientInfo , &clientSize);
            if(connectionFd < 0)
                continue;
                    send(connectionFd , &serverSocket , sizeof(int) , 0);
            recv(serverSocket , &choice , sizeof(int),0);
            close(connectionFd);
            break;
        }
        printf("CHOICE IS :%d\n",choice);
        return 0;
    }

3 ответа

После проверки выясняется, что произошла ошибка при отправке и получении как на клиенте, так и на сервере.

как на странице руководства

ssize_t send (int sockfd, const void * buf, size_t len, int flags);

ssize_t recv (int sockfd, void * buf, size_t len, int flags);

как в моем коде

отправить (clientSocket, & choice, sizeof (int), 0);

recv (serverSocket, & choice, sizeof (int), 0);

что вызывает ошибку, если я применяю каждую функцию правильно?

Ты уверен, что это не так send-ную? ИМО,

recv(clientSocket , &serverSocket , sizeof(int) , 0);

в клиенте блокирует, тем самым не доходя до send() вызов. Вы можете поставить recv() позвонить [что не предназначено и не требуется, IMO] после send() на стороне клиента?

Подсказка: сервер прослушивает входящее соединение, и, пока нет входящего соединения, у него нет адреса для send общение обратно.

  • Общий поток для сервера: открытый сокет -> связать -> прослушать -> принять -> получить -> отправить.
  • Общий поток для клиента: открыть сокет -> подключиться -> отправить -> получить.

РЕДАКТИРОВАТЬ:

Как вы отправляете int тип, [размер больше 1 байта], я бы рекомендовал использовать htonl() на стороне клиента и ntohl() на стороне сервера, чтобы решить проблему с порядком байтов [если есть].

Строка в коде сервера, которая делает:

 send(connectionFd , &serverSocket , sizeof(int) , 0);

не нужно, поэтому удалите его. Нет причин отправлять значение сокета сервера клиенту, клиент все равно не может его использовать, файловый дескриптор является ресурсом, связанным с процессом, и вы не можете передать этот ресурс другому процессу, записав его значение поверх TCP-соединение с клиентом.

На клиенте вам нужно отправить переменную выбора для только что открытого соединения, поэтому вам нужно изменить эти 2 строки:

recv(clientSocket , &serverSocket , sizeof(int) , 0);
send(serverSocket , &choice , sizeof(int),0);

К этому:

 send(clientSocket , &choice , sizeof(int),0);

В дополнение к этому, вы должны иметь привычку проверять все ваши звонки на наличие ошибок, чтобы вы знали, если что-то не получается, например,

int rc;

rc = send(clientSocket , &choice , sizeof(int),0);
if (rc == -1) {
    perror("send()");
    //handle error, e.g. exit the app
}
Другие вопросы по тегам