从服务器发送到客户端

时间:2017-02-22 00:21:28

标签: c sockets

每当客户端执行recv()命令时,我都会尝试将数据从服务器发送到客户端。由于代码现在,我无法让客户端打印它收到的任何数据。我无法弄清楚我的服务器或客户端是否有问题,所以任何帮助都会受到赞赏。谢谢!

client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip.h>


#define ECHO_PORT 9999
#define BUF_SIZE 4096

int main(int argc, char* argv[])
{
    if (argc != 3)
    {
        fprintf(stderr, "usage: %s <server-ip> <port>",argv[0]);
        return EXIT_FAILURE;
    }

    char buf[BUF_SIZE];

    int status, sock, sock2;
    struct addrinfo hints;
    memset(&hints, 0, sizeof(struct addrinfo));
    struct addrinfo *servinfo; //will point to the results
    hints.ai_family = AF_INET;  //IPv4
    hints.ai_socktype = SOCK_STREAM; //TCP stream sockets
    hints.ai_flags = AI_PASSIVE; //fill in my IP for me

    if ((status = getaddrinfo(argv[1], argv[2], &hints, &servinfo)) != 0)
    {
        fprintf(stderr, "getaddrinfo error: %s \n", gai_strerror(status));
        return EXIT_FAILURE;
    }

    if ((sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1)
    {
        fprintf(stderr, "Socket failed");
        return EXIT_FAILURE;
    }

    if ((connect(sock, (struct sockaddr *) servinfo->ai_addr, servinfo->ai_addrlen)) != 0)
    {
        fprintf(stderr, "Connection failed");
        return EXIT_FAILURE;
    }

    if ((sock2 = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1)
    {
        fprintf(stderr, "Socket failed");
        return EXIT_FAILURE;
    }

    if ((connect(sock2, (struct sockaddr *) servinfo->ai_addr, servinfo->ai_addrlen)) != 0)
    {
        fprintf(stderr, "Connection failed");
        return EXIT_FAILURE;
    }

    while (1) {
        //char msg[BUF_SIZE] = "ashudfshuhafhu";
        //char msg[BUF_SIZE]; 
        //fgets(msg, BUF_SIZE, stdin);
        //int i = 2;
        //if (strlen(msg) == i) 
        //    break;
        int bytes_received;
       // fprintf(stdout, "Sending %s", msg);
        //send(sock, msg , strlen(msg), 0);
        if((bytes_received = recv(sock, buf, BUF_SIZE, 0)) > 1)
        {
            buf[bytes_received] = '\0';
            fprintf(stdout, "Received %s", buf);
        }
    }


    freeaddrinfo(servinfo);
    close(sock);    
    return EXIT_SUCCESS;

}

Server.c

#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

#define ECHO_PORT 9999
#define BUF_SIZE 4096

int close_socket(int sock)
{
        if (close(sock))
        {
                fprintf(stderr, "Failed closing socket.\n");
                return 1;
        }
        return 0;
}

int main(int argc, char* argv[])
{
    int sock, client_sock;
    ssize_t readret;
    socklen_t cli_size;
    struct timeval tv;
    struct sockaddr_in addr, cli_addr;
    char buf[BUF_SIZE] = "wetwetwetwetwetwetwetwet";
    fd_set readfds, writefds;
    fd_set activereadfds, activewritefds;
    cli_size = sizeof(&cli_addr);

    tv.tv_sec = 5;
    tv.tv_usec = 0;

    fprintf(stdout, "----- Echo Server -----\n");

    /* all networked programs must create a socket */
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1)
    {
            fprintf(stderr, "Failed creating socket.\n");
            return EXIT_FAILURE;
    }

    addr.sin_family = AF_INET;
    addr.sin_port = htons(ECHO_PORT);
    addr.sin_addr.s_addr = INADDR_ANY;

    /* servers bind sockets to ports---notify the OS they accept connections */
    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)))
    {
            close_socket(sock);
            fprintf(stderr, "Failed binding socket.\n");
            return EXIT_FAILURE;
    }


    if (listen(sock, 5))
    {
            close_socket(sock);
            fprintf(stderr, "Error listening on socket.\n");
            return EXIT_FAILURE;
    }

    FD_ZERO(&readfds);
    FD_SET(sock, &activereadfds);

    while (1)
    {
        fprintf(stdout,"in here.\n");
        readfds = activereadfds;
        writefds = activewritefds;
        FD_ZERO(&activereadfds);
        FD_ZERO(&activewritefds);

        if (select(51, &readfds, &writefds, NULL, &tv) < 0)
        {
            perror("select");
            return EXIT_FAILURE;
        }


        for (int i = 0; i < 10; ++i)
        {
            if (FD_ISSET (i, &readfds))
            {
                if (i == sock)
                {
                    fprintf(stdout, "main loop. \n");
                    client_sock = accept(sock, 
                                (struct sockaddr *) &cli_addr, &cli_size);
                    FD_SET(client_sock, &activereadfds);
                    FD_SET(client_sock, &activewritefds);
                    if (client_sock < 0)
                    {
                        perror("accept");
                        return EXIT_FAILURE;
                    }
                } else {
                        fprintf(stdout, "second loop \n");
                        readret = send(i,buf, strlen(buf),0);

                        if (readret < 0)
                            fprintf(stdout, "yay");
                        }
                }
            if (FD_ISSET(i, &writefds))
                {   fprintf(stdout, "ugh \n");
                    readret = send(i,buf,BUF_SIZE,0);
                    //if (readret > 0)
                    //while((readret = recv(i, buf, BUF_SIZE, 0)) >= 1)
                    //  {

                                //if (send(i, buf, readret, 0) != readret)
                                //{
                                //  close_socket(i);
                                //  close_socket(sock);
                                //  fprintf(stderr, "Error sending to client.\n");
                                //  return EXIT_FAILURE;
                                //}
                }
            }
        }
    close_socket(sock);

    return EXIT_SUCCESS;
}

1 个答案:

答案 0 :(得分:2)

  1. 只有当套接字准备好读取时,您的服务器发送,并且由于客户端永远不会发送,服务器也不是。当客户端套接字在writefds中出现时,服务器发送应该发生,尽管实际上这不是使用该功能的正确方法。真的,你应该发送,只有在writefds导致EAGAIN / EWOULDBLOCK时才会加入并担心send()

  2. 您可能在客户端中收到未检测到的错误:

    if((bytes_received = recv(sock, buf, BUF_SIZE, 0)) > 1)
    {
        buf[bytes_received] = '\0';
        fprintf(stdout, "Received %s", buf);
    }
    

    这应该继续:

    else if (bytes_received == 0)
    {
        fprintf(stdout, "peer disconnected\n");
        break;
    }
    else // < 0: error
    {
        fprintf(stdout, "recv() error %s\n", strerror(errno));
        break;
    }
    

    每当您从系统调用中收到错误时,您都需要打印这样的实际错误。