【问题标题】:Sending date and time as a TCP server welcome message发送日期和时间作为 TCP 服务器欢迎消息
【发布时间】:2020-11-07 04:01:08
【问题描述】:

我必须插入此代码:

time_t ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));

将某人连接到服务器时显示的消息从“Hello student!\n”更改为当前时间和日期,但我不知道在程序中将这两行代码复制到哪里以及我有什么复制这两行后在代码中修改。

#include <stdio.h>      
#include <sys/types.h>
#include <sys/socket.h>   
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h> 

const char MESSAGE[] = "Hello student!\n";

int main(int argc, char *argv[]) {
    int simpleSocket = 0;
    int simplePort = 0;
    int returnStatus = 0;
    struct sockaddr_in simpleServer;
    
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <port>\n", argv[0]);
        exit(1);
    }

    simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (simpleSocket == -1) {
        fprintf(stderr, "Could not create a socket!\n");
        exit(1);
    }
    else {
        fprintf(stderr, "Socket created!\n");
    }

    /* retrieve the port number for listening */
    simplePort = atoi(argv[1]);

    /* setup the address structure */
    /* use INADDR_ANY to bind to all local addresses  */
    memset(&simpleServer, '\0', sizeof(simpleServer)); 
    simpleServer.sin_family = AF_INET;
    simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);
    simpleServer.sin_port = htons(simplePort);

    /*  bind to the address and port with our socket  */
    returnStatus = bind(simpleSocket,(struct sockaddr *)&simpleServer,sizeof(simpleServer));

    if (returnStatus == 0) {
        fprintf(stderr, "Bind completed!\n");
    }
    else {
        fprintf(stderr, "Could not bind to address!\n");
        close(simpleSocket);
        exit(1);
    }

    /* lets listen on the socket for connections      */
    returnStatus = listen(simpleSocket, 5);

    if (returnStatus == -1) {
        fprintf(stderr, "Cannot listen on socket!\n");
        close(simpleSocket);
        exit(1);
    }

    while (1)
    {
        struct sockaddr_in clientName = { 0 };
        int simpleChildSocket = 0;
        int clientNameLength = sizeof(clientName);

        /* wait here */
        simpleChildSocket = accept(simpleSocket,(struct sockaddr *)&clientName, &clientNameLength);

        if (simpleChildSocket == -1) {
            fprintf(stderr, "Cannot accept connections!\n");
            close(simpleSocket);
            exit(1);
        }

        /* handle the new connection request  */
        /* write out our message to the client */
        write(simpleChildSocket, MESSAGE, strlen(MESSAGE));
        close(simpleChildSocket);
    }

    close(simpleSocket);
    return 0;
}

感谢您的回答

【问题讨论】:

    标签: c sockets tcp server write


    【解决方案1】:

    一点介绍:关于原程序

    程序开始创建一个套接字并将其设置为侦听特定端口,并使用programName &lt;port&gt; 等命令行作为参数传递给您的程序。

    使用simplePort = atoi(argv[1]); 行检索端口号。本来可以对参数进行更严格的检查(atoi() 不检查是否实际提供了数字),但我想这对于入门级教育计划来说是可以的。


    之后,用线

    simpleChildSocket = accept(simpleSocket,(struct sockaddr *)&clientName, &clientNameLength);
    

    accept() 函数会阻塞,直到收到来自 TCP 客户端的连接请求。一旦 TCP 握手完成(SYN/SYN-ACK/ACK,它是 三次握手)返回一个套接字句柄(在您的情况下为simpleChildSocket),可用于与客户端交换数据。


    欢迎辞

    接受完成后,我们确信一切顺利,我们很快就会收到欢迎信息。随着线条

    /* write out our message to the client */
    write(simpleChildSocket, MESSAGE, strlen(MESSAGE));
    

    MESSAGE 字符串中包含的字符(用常量const char MESSAGE[] = "Hello student!\n"; 定义)通过write() 函数发送。它的参数是

    • 套接字描述符
    • 指向要发送的缓冲区的指针
    • 要发送的字节数(本例对应MESSAGE的长度,用strlen(MESSAGE)计算

    注意: write 函数实际上可以使用,但它是一个非常规的选择。事实上,它是一个通用函数,但在写入套接字时,实际上使用了send()


    如何实现你的目标

    您所要做的就是将write() 调用中的MESSAGE 替换为包含日期的字符串:

    {
        char buff[30+1];
        time_t ticks = time(NULL);
        snprintf(buff, sizeof(buff), "%.30s\r\n", ctime(&ticks));
    
        /* write out our message to the client */
        write( simpleChildSocket, buff, strlen(buff) );
    }
    

    不要忘记定义您的 buff 字符缓冲区。我是在本地定义的,你也可以动态分配。

    你的老师提供的代码复制了buff数组中ctime()的时间计算(我增加了它的大小以确保整个datetime可以包含在其中) .

    然后我们像以前一样调用write,只需将MESSAGEstrlen(MESSAGE) 替换为新字符串buffstrlen(buff)

    【讨论】:

    • 这不是我想要的答案。我要求将这两行代码放入代码中以使其适合而不是更改所有代码。不过谢谢
    • @ema 我没有更改所有代码,我只更改了这两行。很抱歉您不喜欢我的回答,因为我在解释您的代码和问题方面付出了很多努力。
    • 很抱歉,我再次阅读了该消息,但我在第一次阅读时误解了它。对不起
    • @Ema 没关系。我希望它有助于理解所有程序的作用,而不仅仅是你的作业需要的两行。 ;)
    • 是的,它有很大帮助,非常感谢。我真的很感激,谢谢
    【解决方案2】:

    我已经解决了

    #include <stdio.h>      
    #include <sys/types.h>
    #include <sys/socket.h>   
    #include <netdb.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <time.h> 
    
    /*const*/ char MESSAGE[100] = "";
    char buff[100];
    
    int main(int argc, char *argv[]) {
    
        int simpleSocket = 0;
        int simplePort = 0;
        int returnStatus = 0;
        struct sockaddr_in simpleServer;
        
        if (argc != 2) {
    
            fprintf(stderr, "Usage: %s <port>\n", argv[0]);
            exit(1);
    
        }
    
        simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
        if (simpleSocket == -1) {
    
            fprintf(stderr, "Could not create a socket!\n");
            exit(1);
    
        }
        else {
            fprintf(stderr, "Socket created!\n");
        }
    
        /* retrieve the port number for listening */
        simplePort = atoi(argv[1]);
    
        /* setup the address structure */
        /* use INADDR_ANY to bind to all local addresses  */
        memset(&simpleServer, '\0', sizeof(simpleServer)); 
        simpleServer.sin_family = AF_INET;
        simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);
        simpleServer.sin_port = htons(simplePort);
    
        /*  bind to the address and port with our socket  */
        returnStatus = bind(simpleSocket,(struct sockaddr *)&simpleServer,sizeof(simpleServer));
    
        if (returnStatus == 0) {
            fprintf(stderr, "Bind completed!\n");
        }
        else {
            fprintf(stderr, "Could not bind to address!\n");
        close(simpleSocket);
        exit(1);
        }
    
        /* lets listen on the socket for connections      */
        returnStatus = listen(simpleSocket, 5);
    
        if (returnStatus == -1) {
            fprintf(stderr, "Cannot listen on socket!\n");
        close(simpleSocket);
            exit(1);
        }
    
        while (1)
    
        {
    
            struct sockaddr_in clientName = { 0 };
        int simpleChildSocket = 0;
        int clientNameLength = sizeof(clientName);
    
        /* wait here */
    
            simpleChildSocket = accept(simpleSocket,(struct sockaddr *)&clientName, &clientNameLength);
    
        if (simpleChildSocket == -1) {
    
                fprintf(stderr, "Cannot accept connections!\n");
            close(simpleSocket);
            exit(1);
    
        }
    
        /* handle the new connection request  */
        /* write out our message to the client */
        
        time_t ticks = time(NULL);
        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
        strcpy(MESSAGE, buff);
        write(simpleChildSocket, MESSAGE, strlen(MESSAGE));
            close(simpleChildSocket);
        }
    
        close(simpleSocket);
        return 0;
    
    }
    

    【讨论】:

    • 您的解决方案基本上是我在回答中建议的,但我建议您检查我的解决方案。实际上,您将buff 不必要地复制到MESSAGE。可以直接发送buff(或者传MESSAGE给ctime)。
    • 我忘了说练习要我们使用缓冲区,抱歉
    • buff 是一个缓冲区。 :)
    猜你喜欢
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    相关资源
    最近更新 更多