请教一个折腾好几天的问题, udp 收发小实验

2015-04-26 19:03:29 +08:00
 gzxultra

系统是Macintosh Yosemite,编译器gcc

实验的基本内容是客户端发消息,服务器端回显,
这里做在同一台电脑上用两个终端联系,

但是接下来麻烦来了

客户端显示莫名其妙的字符(好像是之前测试输入的。。跟本次输入完全没有关系)
用很原始的调试方法发现,客户端显示的东西完全不是服务器端返回的(服务器端get sendline!这句话根本就不执行。。。)

是我代码的问题还是电脑的问题
能帮我解释一下为什么么?十分感谢!

最后附代码

/*
 * udpcli01.cpp
 *
 *  Created on: 2015年4月23日
 *      Author: gzxultra
 */

    #include        <netinet/in.h>
    #include        <errno.h>
    #include        <stdio.h>
    #include        <stdlib.h>
    #include        <sys/socket.h>
    #include        <string.h>
    #include        <arpa/inet.h>
    #define MAXLINE                  4096
    #define LISTENQ                  1024    /* 2nd argument to listen() */
    #define SERV_PORT                9877
    #define SA      struct sockaddr


    void dg_cli(FILE *, int, const SA *, socklen_t);

    int
    main(int argc, char **argv)
    {
        int sockfd;
        struct sockaddr_in servaddr;

        if (argc != 2) {
            printf("usage:udpcli01sigio <IPaddress>\n");
            exit(1);
        }

        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(SERV_PORT);

        inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

        if((sockfd = socket(AF_INET, SOCK_DGRAM, 0))<0) {
            printf("socket error.\n");
            exit(1);
        }

        dg_cli(stdin, sockfd, (SA *)&servaddr, sizeof(servaddr));

        exit(0);
    }

    void
    dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
    {
        int  n;
        char sendline[MAXLINE], recvline[MAXLINE + 1];
        //struct sockaddr_in from;

        while (fgets(sendline, MAXLINE,fp) != NULL) {
            sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
            n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
            recvline[n] = 0; /* null terminate */
            fputs(recvline, stdout);
            memset(sendline,0,sizeof(sendline));
            memset(recvline,0,sizeof(recvline));
        }
    }
/*
 * udpserv01.cpp
 *
 *  Created on: 2015年4月23日
 *      Author: gzxultra
 */

#include        <netinet/in.h>
#include        <errno.h>
#include        <stdio.h>
#include        <stdlib.h>
#include        <sys/socket.h>
#include        <arpa/inet.h>
#define MAXLINE                  4096
#define LISTENQ                  1024    /* 2nd argument to listen() */
#define SERV_PORT                9877
#define SA      struct sockaddr
#include    <string.h>


static int sockfd;
void dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen, char *mesg);
//void GetList(int sockfd, SA *pcliaddr, socklen_t clilen) ;

int main(int argc, char ** argv) {

    struct sockaddr_in servaddr, cliaddr;

    //使用socket()函数生成套接字文件描述符
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        printf("socket error.\n");
        exit(1);
    }
    //printf("I am not dead!\n");

    //设置服务器地址和侦听端口,初始化要绑定的网络地址结构
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;                      //地址类型为AF_INET
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);       //任意本地地址
    servaddr.sin_port = htons(SERV_PORT);               //服务器端口

    //绑定侦听端口
    bind(sockfd, (SA *) &servaddr, sizeof(servaddr));

/*
    char instruction[3][10] = {
        "getlist\0",
        "download\0",
        "upload\0"
    };
*/
    int op = 0;
    int i = 0,j = 0;
    int n = 0;
    char mesg[MAXLINE];
    socklen_t len = sizeof(cliaddr);
    printf("running here!\n");
    while(1){
        //len = clilen;

        //recvfrom接收客户端的网络数据
        //printf("running here2!\n");
        n = recvfrom(sockfd, mesg, MAXLINE, 0, (SA *) &cliaddr,  &len);
        printf("get sendline!\n");

        dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), mesg);
        printf("echo done!\n");
    }
}

void dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen, char *mesg) {

    sendto(sockfd, mesg, sizeof(mesg), 0, pcliaddr, clilen);

}
2905 次点击
所在节点    Linux
6 条回复
xenme
2015-04-26 19:40:35 +08:00
recvfrom没收到消息,就会一直阻塞
所以,就一直卡在那里了
gzxultra
2015-04-26 19:45:36 +08:00
@xenme
就是想知道为啥recvfrom没收到消息
网络不好?系统问题还是代码错了?
感谢!
zhjits
2015-04-26 19:49:38 +08:00
@gzxultra 你用 Wireshark 抓包看看
kkfnui
2015-04-26 21:11:01 +08:00
没有收到数据的原因:
1. 运行client程序,传入的ip地址错误的,我第一遍输入127.0.0.1 确实出现了楼主说的情况
2. 系统有防火墙,禁止server程序传入数据

乱码的原因,是你接收数据的缓冲区没有初始化了。

变量定义的时候初始化是个好习惯。
catro
2015-04-27 12:35:23 +08:00
关于显示莫名字符串的问题
1. 字符串取长度用strlen,代码里好多用了sizeof。
2. 客户端传给服务端的字符串不带0,服务端取长度前要加0。

不回显的问题参考3楼用Wireshark分析。
gzxultra
2015-04-27 16:47:29 +08:00
@catro

首先感谢热心解答,莫名字符串已修改

关于无法recvfrom的问题也已经发现原因和解决方法
习惯sublime先手编译一下,command+b 实际上运行了程序(开了一个服务器进程)
命令行执行开了一个服务器进程,
因为有两个服务器端口,client端无法正确发送!!!
折磨我几天了,再次感谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/186484

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX