这是我的第一个问题,请允许。我正在努力学习Unix的C套接字。作为学习的一部分,我尝试编写一个类似telnet的简单客户端,该客户端连接到指定端口上的主机,打印从服务器接收到的任何字符,并将用户写入的任何内容发送到控制台。它收到罚款,但当我试图发送字符串,什么也没有发生。然后,当我中断程序时,我试图发送的所有字符串都会被发送。提前谢谢。我可能只是在装傻。

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

int SetupSock(char *host, char *port) {
    int s, status;
    struct addrinfo hints, *res;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    getaddrinfo(host, port, &hints, &res);
    if((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {
        printf("Could not create sock...root?\n");
        exit(1);
    }
    if((status = connect(s, res->ai_addr, res->ai_addrlen)) == -1) {
        printf("Connect Failed: %s\n", strerror(errno));
        printf("%s", strerror( errno ));
        printf("\n");
        exit(1);
    }
    return s;
}

int main (void) {
    char *host = malloc(100), *port = malloc(20), buf[2], *msg = malloc(1000);
    struct timeval waitid;
    fd_set read_flags, write_flags;
    signal(SIGPIPE, SIG_IGN);
    int sock, flags;
    //Input Host and Port
    printf("Host: ");
    gets(host);
    printf("Port: ");
    gets(port);
    sock = SetupSock(host, port);
    flags = fcntl(sock, F_GETFL, 0);
    fcntl(sock, F_SETFL, flags | O_NONBLOCK);
    FD_ZERO(&read_flags);
    FD_ZERO(&write_flags);
    FD_SET(sock, &read_flags);
    FD_SET(fileno(stdin), &read_flags);
    fflush(0);
    int pid = fork();
    if (pid == 0) {
        int status;
        close(stdout);
        while(1) {
        select(sock + 1, &read_flags, &write_flags, (fd_set*) 0, &waitid);
        if (FD_ISSET(fileno(stdin), &read_flags)) {
            gets(msg);
            if((status = send(sock, msg, strlen(msg), MSG_NOSIGNAL)) == -1) {
                printf("Send Failed: %s\n", strerror(errno));
            }
        }
        }
    }
    else {
        close(stdin);
        while(1) {
            select(sock + 1, &read_flags, &write_flags, (fd_set*) 0, &waitid);
            if (FD_ISSET(sock, &read_flags)) {
                if(recv(sock, &buf, 1, 0) > 0){
                    printf("%s", buf);
                }
            }
        }
    }
    close(sock);
    return 0;
}

最佳答案

您的select在此仅执行一次。它应该在一个循环中。
select只需等待在提供的文件描述符集上发生事件。
在处理完每个事件之后,应该再次调用它。

07-24 09:43
查看更多