控制命令行的提示

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

我的代码如下

[服务器]

#include  #include  #include  #include  #include  #include  #include  #include  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  #include  #include  #include  #include  #include  #include  #include  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上。

我问另一个线程命令提示符不能接受带有更简单示例的消息 。

你从终端得到了流浪的新行。 不确定是什么导致它。 如果空白行无效输入,您可以通过忽略以’\ 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语句但是要处理不同的平台。

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

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

现在变得更好了。