recvfrom的最后一个参数不赋值时,返回的是一个很大的数。赋值后就是正常的
服务器端:
#include
#include
#include
#include
#include
#include
#define SERV_PORT 9999
#define BUF_LEN 128
void dg_echo(int sockfd, struct sockaddr_in *pcliaddr, socklen_t clilen)
{
char buf[BUF_LEN];
socklen_t len;
int n;
for (;;) {
len = clilen;
if ((n = recvfrom(sockfd, buf, BUF_LEN, 0, (struct sockaddr*)pcliaddr, &len)) < 0) {
printf("recvfrom error:%s\n", strerror(errno));
continue;
}
sendto(sockfd, buf, n, 0, (struct sockaddr*)pcliaddr, len);
}
}
int main(int argc, char **argv)
{
struct sockaddr_in servaddr, clientaddr;
int sockfd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
printf("socket error:%s\n", strerror(errno));
return -1;
}
memset(&servaddr, 0x00, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
if (bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
printf("bind error:%s\n", strerror(errno));
close(sockfd);
return -1;
}
dg_echo(sockfd, &clientaddr, sizeof(clientaddr));
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_PORT 9999
#define BUF_LEN 128
char *sock_ntop(const struct sockaddr* sockaddr, socklen_t len)
{
static char str[BUF_LEN];
char portstr[7];
printf("sa_family1=%d, AF_INET=%d\n", sockaddr->sa_family, AF_INET);
switch (sockaddr->sa_family) {
case AF_INET:
printf("enter...\n");
struct sockaddr_in *sin = (struct sockaddr_in*)sockaddr;
if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == (const char *)NULL) {
printf("inet_ntop error:%s\n", strerror(errno));
return NULL;
}
if (ntohs(sin->sin_port) != 0) {
snprintf(portstr, sizeof(portstr), ":%d", ntohs(sin->sin_port));
strcat(str, portstr);
}
return str;
}
return NULL;
}
void dg_cli(FILE *fp, int sockfd, const struct sockaddr_in * pservaddr, socklen_t servlen)
{
int n;
char sendline[BUF_LEN], recvline[BUF_LEN];
struct sockaddr reply_addr;
socklen_t len;
while (fgets(sendline, BUF_LEN, fp) != NULL) {
sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr*)pservaddr, servlen);
//memset(&reply_addr, 0x00, sizeof(reply_addr));
len = servlen;
n = recvfrom(sockfd, recvline, BUF_LEN, 0, &reply_addr, &len);
printf("sa_family=%d, servlen=%d, len=%d\n", reply_addr.sa_family, servlen, len);
if (len != servlen || memcmp(&reply_addr, pservaddr, len) != 0) {
printf("receive (%s) ignored\n", sock_ntop(&reply_addr, len));
continue;
}
recvline[n] = 0;
fputs(recvline, stdout);
}
}
int main(int argc, char **argv)
{
struct sockaddr_in servaddr;
int sock;
memset(&servaddr, 0x00, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0) {
printf("inet_pton error:%s\n", strerror(errno));
return -1;
}
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
printf("socket error:%s\n", strerror(errno));
return -1;
}
dg_cli(stdin, sock, &servaddr, sizeof(servaddr));
return 0;
}
输出为:
客户端没有赋值时,输出的乱码:
#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_PORT 9999
#define BUF_LEN 128
char *sock_ntop(const struct sockaddr* sockaddr, socklen_t len)
{
static char str[BUF_LEN];
char portstr[7];
printf("sa_family1=%d, AF_INET=%d\n", sockaddr->sa_family, AF_INET);
switch (sockaddr->sa_family) {
case AF_INET:
printf("enter...\n");
struct sockaddr_in *sin = (struct sockaddr_in*)sockaddr;
if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == (const char *)NULL) {
printf("inet_ntop error:%s\n", strerror(errno));
return NULL;
}
if (ntohs(sin->sin_port) != 0) {
snprintf(portstr, sizeof(portstr), ":%d", ntohs(sin->sin_port));
strcat(str, portstr);
}
return str;
}
return NULL;
}
void dg_cli(FILE *fp, int sockfd, const struct sockaddr_in * pservaddr, socklen_t servlen)
{
int n;
char sendline[BUF_LEN], recvline[BUF_LEN];
struct sockaddr reply_addr;
socklen_t len;
while (fgets(sendline, BUF_LEN, fp) != NULL) {
sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr*)pservaddr, servlen);
//memset(&reply_addr, 0x00, sizeof(reply_addr));
//len = servlen;
n = recvfrom(sockfd, recvline, BUF_LEN, 0, &reply_addr, &len);
printf("sa_family=%d, servlen=%d, len=%d\n", reply_addr.sa_family, servlen, len);
if (len != servlen || memcmp(&reply_addr, pservaddr, len) != 0) {
printf("receive (%s) ignored\n", sock_ntop(&reply_addr, len));
continue;
}
recvline[n] = 0;
fputs(recvline, stdout);
}
}
int main(int argc, char **argv)
{
struct sockaddr_in servaddr;
int sock;
memset(&servaddr, 0x00, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0) {
printf("inet_pton error:%s\n", strerror(errno));
return -1;
}
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
printf("socket error:%s\n", strerror(errno));
return -1;
}
dg_cli(stdin, sock, &servaddr, sizeof(servaddr));
return 0;
}
哦,原来是这样的
recvfrom()
recvfrom() places the received message into the buffer buf. The
caller must specify the size of the buffer in len.
If src_addr is not NULL, and the underlying protocol provides the
source address of the message, that source address is placed in the
buffer pointed to by src_addr. In this case, addrlen is a value-
result argument. Before the call, it should be initialized to the
size of the buffer associated with src_addr. Upon return, addrlen is
updated to contain the actual size of the source address. The
returned address is truncated if the buffer provided is too small; in
this case, addrlen will return a value greater than was supplied to
the call.
If the caller is not interested in the source address, src_addr and
addrlen should be specified as NULL.
Before the call, it should be initialized to the
size of the buffer associated with src_addr. Upon return, addrlen is
updated to contain the actual size of the source address.