我使用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更简单的例子。
答案 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。
现在变得更好。