网络编程学习笔记(recvfrom很奇怪的一个地方)
2014-09-28 22:02
246 查看
recvfrom的最后一个参数不赋值时,返回的是一个很大的数。赋值后就是正常的
服务器端:
客户端赋值时:
客户端没有赋值时,输出的乱码:
输出就不正确,接收的长度及sa_family都是不正确的
哦,原来是这样的
当中有这样一段话:
服务器端:
#include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <stdio.h> #include <errno.h> #include <string.h> #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 <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #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 = 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 <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #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 = 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; }
输出就不正确,接收的长度及sa_family都是不正确的
哦,原来是这样的
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.
相关文章推荐
- 网络编程学习笔记二(实现一个基于简单TCP的用户注册程序)
- 网络编程学习笔记(recvfrom和sendto函数)
- Java UDP 网络编程 示例 -Java学习笔记(30)
- 网络编程学习笔记
- Java学习笔记之网络编程基础-通过URL获取HTML页面
- [Linux网络编程学习笔记]FIFO的创建和使用
- Java 网络编程 学习笔记一 基础知识
- Java 网络编程 TCP vs UDP -Java学习笔记(31)
- 孙鑫VC++视频学习笔记之14:网络编程
- Java学习笔记之网络编程基础-通过URL获取网络图片
- Java学习笔记之网络编程基础-获取本机名称
- [Linux网络编程学习笔记]管道的创建和使用
- [原]Linux网络编程学习笔记
- 孙鑫VC学习笔记:第十四讲 (二) 网络编程
- Java学习笔记之网络编程基础-通过URLConnection获取HTML页面
- 《Web Service 编程 --用C#.NET 开发网络服务》北京希望出版社 我的学习笔记(第二章)(也就是书上抄了一写东西而已)
- C#网络编程学习笔记1
- 传智博客学习笔记15--JAVA网络编程
- 网络工程师_一个学习笔记(1.2)
- Java 网络编程 学习笔记二 Socket 用法