控制命令行的提示

时间:2014-03-07 11:24:13

标签: c loops command-line while-loop prompt

我使用C。

制作了基于udp的客户端和服务器示例程序

我的代码如下

[服务器]

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


    int printerror2(char func[], int errnum)
    {
        printf("%s error = %d:%s\n", func, errnum, strerror(errnum));
        perror(func);
        return errnum;
    }

    int printerror(char func[])
    {
        return printerror2(func, errno);
    }

    int main(int argc, char *argv[])
    {
        int ret;
    /*
        WSADATA wsaData;
        ret = WSAStartup(MAKEWORD(2,2), &wsaData);
        if (ret != 0)
            return printerror2("WSAStartup()", ret);
    */
        int sock;
        int port;
        struct sockaddr_in addr;
        struct sockaddr_in from;
        int from_size;

        char buf[2048];

        port = atoi(argv[1]);
        printf("############# udpServer port number is %hu\n", port);

        sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (sock == -1)
            return printerror("socket()");

        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = INADDR_ANY;

        ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
        if (ret == -1)
            return printerror("bind()");

        do
        {
            from_size = sizeof(from);

            ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&from, &from_size);
            if (ret == -1)
                return printerror("recvfrom()");

            printf("received '%*s'(%d) from %s:%d\n",
                ret, buf, ret, inet_ntoa(from.sin_addr), ntohs(from.sin_port));

            ret = sendto(sock, buf, ret, 0, (struct sockaddr *)&from, from_size);
            if (ret == -1)
                return printerror("sendto()");

            printf("sent back '%*s'(%d) to %s:%d\n",
                ret, buf, ret, inet_ntoa(from.sin_addr), ntohs(from.sin_port));
            printf("\n");
        } 
        while  (strncmp(buf, "bye", 3) != 0);

        printf("bye now");

        close(sock);
        return 0;

[客户]

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

int printerror2(char func[], int errnum)
{
    printf("%s error = %d:%s\n", func, errnum, strerror(errnum));
    perror(func);
    return errnum;
}

int printerror(char func[])
{
    return printerror2(func, errno);
}

int getMyPortNum(int sock, int *port)
{
    struct sockaddr_in s;
    socklen_t sz = sizeof(s);
    int ret = getsockname(sock, (struct sockaddr *)&s, &sz);
    if (ret == 0)
       *port = s.sin_port;
    printf("getsockname() error ret = %d:%s\n",ret,strerror(errno));
    printf("Client port(getsockname) is %d\n", ntohs(*port));
    return ret;
}

int main(int agrc, char *argv[])
{
    int ret;
/*
    WSADATA wsaData;
    ret = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (ret != 0)
        return printerror2("WSAStartup", ret);
*/
    char *host;
    int port;
    int sock;
    struct sockaddr_in dst_addr;
    struct sockaddr_in src_addr;
    struct sockaddr_in from_addr;
    int from_size;

    char message[2048];
    char comnd[2048];
    char buf[2048];

    host = argv[1];
    port = atoi(argv[2]);

    printf("host = %s\n", host);
    printf("port = %d\n", port);

    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock == -1)
        return printerror("socket()");

    memset(&src_addr, 0, sizeof(src_addr));
    src_addr.sin_family = AF_INET;
    src_addr.sin_addr.s_addr = INADDR_ANY;
    src_addr.sin_port = 0;

    ret = bind(sock, (struct sockaddr *)&src_addr, sizeof(src_addr));
        printf("bind() error ret = %d:%s\n",ret,strerror(errno));
   if (ret == -1)
        return printerror("bind()");

    ret = getMyPortNum(sock, &(src_addr.sin_port));
    printf("Client port(getsockname) is %d\n", ntohs(src_addr.sin_port));
    if (ret == -1)
        return printerror("getsockname()");

    printf("Client port is %d\n", ntohs(src_addr.sin_port));

    memset(&dst_addr, 0, sizeof(dst_addr));
    dst_addr.sin_family = AF_INET;
    dst_addr.sin_addr.s_addr = inet_addr(host);
    dst_addr.sin_port = htons(port);

    do
    {
        printf("type your message (exit: stop Client, bye: stop server)>>>\t"); 
        fgets(buf, sizeof(buf), stdin);

        if (strcmp(buf, "exit") == 0)
            break;

        ret = sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&dst_addr, sizeof(dst_addr));
        if (ret == -1)
            return printerror("sendto()");

        printf("Waiting for send back !!!\n");

        from_size = sizeof(from_addr);

        ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&from_size, &from_size); 
        if (ret == -1)
            return printerror("recvfrom()");

        printf("Received '%*s' from %s:%d\n",
            ret, buf, inet_ntoa(from_addr.sin_addr), ntohs(from_addr.sin_port));
    }
    while ((strncmp(buf, "bye", 3) != 0)&&(strncmp(buf, "exit", 4) != 0));

    close(sock);
    return 0;

客户端显示提示,使操作员向服务器输入一些消息。

服务器向客户端发送消息,告知客户端最初发送的内容。

但客户端发送消息3次而不等待提示和操作员操作如下。

[客户]

type your message (exit: stop Client, bye: stop server)>>>      ping

Waiting for send back !!!
Received '
' from 0.0.0.0:1
type your message (exit: stop Client, bye: stop server)>>>      Waiting for send back !!!
Received 'ping
' from 0.0.0.0:1
type your message (exit: stop Client, bye: stop server)>>>      Waiting for send back !!!
Received '
' from 0.0.0.0:1
type your message (exit: stop Client, bye: stop server)>>>

此外,服务器还收到3条消息,包括我输入的ping和我没想到的消息。

[服务器]

received '
'(1) from 127.0.0.1:52804
sent back '
'(1) to 127.0.0.1:52804

received 'ping
'(5) from 127.0.0.1:52804
sent back 'ping
'(5) to 127.0.0.1:52804

received '
ing
'(1) from 127.0.0.1:52804
sent back '
ing
'(1) to 127.0.0.1:52804

现在,我想问你如何让它等待每个提示?

此外,这不会发生在Windows上,只会发生在CentOS上。

我问了另一个帖子 Command prompt can't accept message更简单的例子。

2 个答案:

答案 0 :(得分:1)

你从终端获得了流浪的新行。不确定是什么导致它。如果空白行无效输入,您可以通过忽略以'\ n'开头的行来解决这个问题 - 即:

printf("type your message (exit: stop Client, bye: stop server)>>>\t"); 
do {
    fgets(buf, sizeof(buf), stdin);
} while (buf[0] == '\n');

否则,你必须有一些平台特定的代码来处理清除任何缓冲的输入,在linux上我会看看fpurge(stdin),并在打印提示之前尝试它,你将不得不添加一个标题和#ifdef语句虽然可以处理不同的平台。

答案 1 :(得分:0)

我在输入信息时发送了CR + LF。

然后我更改了终端仿真器的设置以发送LF或CR。

现在变得更好。