问题
I've made udp based client and server sample programs with C.
My codes are followings
[Server]
#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;
[Client]
#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;
The client shows prompt to make operator type some message to the server.
The server echoes message to the client what the originally the client was sent.
But the client send message 3 times without waiting at prompt and operators action like bellow.
[Client]
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)>>>
Also the server receives 3 messages including both ping
I typed and I didn’t expect to.
[Server]
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
Now,I want to ask you how can I make it wait each prompt?
In addition this doesn't happen on windows ,only happens on CentOS.
I asked it another thread Command prompt can't accept message with more simple example.
回答1:
You're getting stray newlines from the terminal. Not sure what is causing it. If a blank line is not valid input, you can solve this by just ignoring lines that start with '\n' -- i.e.:
printf("type your message (exit: stop Client, bye: stop server)>>>\t");
do {
fgets(buf, sizeof(buf), stdin);
} while (buf[0] == '\n');
Otherwise, you will have to have some platform specific code to deal with clearing any buffered input, on linux I would look at fpurge(stdin), and try it before printing the prompt, you'll have to add a header and #ifdef statements to deal with different platforms though.
回答2:
I sent CR+LF when I typed message.
Then I changed setting of terminal emulater to send LF or CR.
Now getting better.
来源:https://stackoverflow.com/questions/22248781/controlling-prompt-for-command-line