服务器无法通过C中的Socket向客户端发送消息

时间:2015-04-12 12:08:38

标签: c sockets pointers server

您好我正在编写2个程序(服务器,客户端),它们应该通过套接字相互通信。客户端能够毫无问题地将其第一条消息发送到服务器,但是当服务器尝试应答时,客户端只收到一个空消息:recv(...)为0。 调用send(...)函数后,服务器突然停止。 这是我的代码:

服务器

    /* Create a new TCP/IP socket `sockfd`, and set the SO_REUSEADDR
       option for this socket. Then bind the socket to localhost:portno,
       listen, and wait for new connections, which should be assigned to
       `connfd`. Terminate the program in case of an error.
    */
    struct sockaddr_in sin,
                    peer_addr;
    //-----gen socket-----//
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        bail_out(EXIT_PARITY_ERROR, "could not create Socket");

    //-----bind-----//
    memset(&sin, 0, sizeof (sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(options.portno);
    sin.sin_addr.s_addr = INADDR_ANY;
    if (bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0)
        bail_out(EXIT_PARITY_ERROR, "Failed to bind to Port");

    //-----listen-----//
    if (listen(sockfd, 5) < 0)
        bail_out(EXIT_PARITY_ERROR, "Server can't accepted connection");

    //-----accept-----//
    int sock_len = sizeof peer_addr;
    if ((connfd = accept(sockfd, (struct sockaddr*)&peer_addr, (socklen_t *)&sock_len)) < 0) //fragen
        bail_out(EXIT_PARITY_ERROR, "Can't accept connection to Client");
    /* accepted the connection */

   //Some other Code which has nothing to do with my Error!

    /* read from client (WORKS FINE!!)*/
    if (read_from_client(connfd, &buffer[0], READ_BYTES) == NULL) {
        if (quit) break; /* caught signal */
            bail_out(EXIT_FAILURE, "read_from_client");
    }
    request = (buffer[1] << 8) | buffer[0];
    DEBUG("Round %d: Received 0x%x\n", round, request);

    /* compute answer */
    correct_guesses = compute_answer(request, buffer, options.secret);
    if (round == MAX_TRIES && correct_guesses != SLOTS) {
        buffer[0] |= 1 << GAME_LOST_ERR_BIT;
    }

    DEBUG("Sending byte 0x%x\n", buffer[0]);


    /* send message to client */
    if (send_to_client(sockfd, &buffer[0], WRITE_BYTES) == NULL) { //Error in this Method!
        if (quit) break; /* caught signal */
            bail_out(EXIT_FAILURE, "can't send message!");
    }

方法:

static uint8_t *send_to_client(int fd, uint8_t *buffer, size_t n)
{
    /* loop, as packet can arrive in several partial reads */
    size_t bytes_send = 0;
    do {
        ssize_t r = send(fd, buffer + bytes_send, n - bytes_send, 0); //Program stops HERE!
        printf("%d\n", (int)r); //This and the following lines will not be executed!
        if (r <= 0) {
            return NULL;
        }
        bytes_send += r;
    } while (bytes_send < n);

    if (bytes_send < n) {
        return NULL;
    }
    return buffer;
}

客户:(可能有用)

sockfd = cnt_to_server(argv[1], argv[2]);
uint8_t buffer;
uint16_t msg_buffer;
    do
    {
        msg_buffer = generate_msg(&msg);
        printf("Sending byte 0x%x\n", msg_buffer);
        if (send_to_server(sockfd, &msg_buffer, WRITE_BYTES) == NULL) //works
            error_exit(EXIT_FAILURE, "can't send message!");
        if (read_from_server(sockfd, &buffer, READ_BYTES) == NULL) //NULL
            error_exit(EXIT_FAILURE, "can't read message!");
        printf("received byte 0x%x\n", buffer);
    } while (game_continue(buffer, &msg));

    (void)close(sockfd);

方法:

uint8_t* read_from_server(int fd, uint8_t *buffer, int n)
{
    /* loop, as packet can arrive in several partial reads */
    size_t bytes_recv = 0;
    do {
        ssize_t r;
        r = recv(fd, buffer + bytes_recv, n - bytes_recv, 0); //0
        printf("%d\n", (int)r);
        if (r <= 0) {
            return NULL;
        }
        bytes_recv += r;
    } while (bytes_recv < n);

    if (bytes_recv < n) {
        return NULL;
    }
    return buffer;
}

int cnt_to_server(const char *par_server, const char *par_port)
{
    struct sockaddr_in server;
    struct hostent *hp;

    int  sockfd;

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        error_exit(EXIT_FAILURE, "could not create Socket");

    server.sin_family = AF_INET;

    if ((hp = gethostbyname(par_server)) == 0)
        error_exit(EXIT_FAILURE, "host error!");

    memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
    server.sin_port = htons(parse_port(par_port));

    if (connect(sockfd, (struct sockaddr*) &server, sizeof server) < 0)
        error_exit(EXIT_FAILURE, "could not connect!");

    return sockfd;
}

帮助我解决这个问题!

2 个答案:

答案 0 :(得分:2)

更改

if (send_to_client(sockfd, &buffer[0], WRITE_BYTES) == NULL)

if (send_to_client(connfd, &buffer[0], WRITE_BYTES) == NULL)

答案 1 :(得分:0)

解决方案是使用connfd(连接套接字的文件描述符)而不是sockfd

    /* read from client */
    if (read_from_client(connfd, &buffer[0], READ_BYTES) == NULL) {
        if (quit) break; /* caught signal */
            bail_out(EXIT_FAILURE, "read_from_client");
    }