免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3437 | 回复: 3
打印 上一主题 下一主题

[C] ipv6 socket通信问题----服务端收到包,程序收不到 [复制链接]

论坛徽章:
5
金牛座
日期:2015-07-03 13:32:00卯兔
日期:2015-07-03 13:32:17程序设计版块每日发帖之星
日期:2015-11-29 06:20:0015-16赛季CBA联赛之同曦
日期:2015-12-15 09:36:06CU十四周年纪念徽章
日期:2016-07-06 17:18:48
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2017-04-25 15:54 |只看该作者 |倒序浏览
本帖最后由 seanking1987 于 2017-04-25 16:05 编辑

服务端代码:
  1. <blockquote>#include <stdio.h>
复制代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <net/if.h>

#define ip_server  "2001:da8:e000::1:1:89"
#define ip_port 3322

int main(int argc, char *argv[])
{
        struct sockaddr_in6 name;
        struct ipv6_mreq mreq;
        int     sock;
        int     val;
        int rc=0;
        int recv_len=0;
        char recvbuf[256];
        struct sockaddr_in6 from_addr6;
        socklen_t addr_len=0;
        fd_set readfdset;
        struct timeval tv;

        memset(&name,0,sizeof (name));
        name.sin6_family = AF_INET6;
        name.sin6_port = htons(ip_port);

        rc=inet_pton(AF_INET6,ip_server, &name.sin6_addr);
        if(rc!=1)
        {
                printf("open_udp_socket_v6 error,inet_pton error!\n";
                return -1;
        }
        //name.sin6_addr = in6addr_any;

        if((sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0)
         {
                printf("open_udp_socket error(socket error)\n";
                return -1;
         }

        val = 1;
       /*bind过程中本地地址可重复使用*/
        if(setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)) < 0)
         {
                close(sock);
                printf("open_udp_socket_v6 error(setsockopt error)\n";
                return -1;
         }

        if(bind(sock,(struct sockaddr*)&name,sizeof(name)) < 0)
         {
                close(sock);
                printf("open_udp_socket_v6 error(bind error)\n";
                return -1;
         }

    while(1)
    {
        FD_ZERO(&readfdset);
        FD_SET(sock,&readfdset);
        tv.tv_sec = 0;
        tv.tv_usec = 1000000;
        rc=select(sock+1,&readfdset,NULL,NULL,&tv);
        if(rc<0)
        {
                printf("receive failed(select error)\n";
                continue;
        }
        if(FD_ISSET(sock,&readfdset))
        {
                addr_len = sizeof(from_addr6);
                memset(&from_addr6, 0, addr_len);
                memset(recvbuf, 0, sizeof(recvbuf));
                recv_len = recvfrom(sock,recvbuf, sizeof(recvbuf) - 1, 0,(struct sockaddr *)&from_addr6, &addr_len);
                if(recv_len < 0)
                {
                        printf("receive error(recvfrom error)\n";
                        continue;
                }
                printf("get length:%d,message is %s\n",recv_len,recvbuf);
        }
    }
}


客户端:
  1. <blockquote>#include <time.h>
复制代码
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <pthread.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <sys/timeb.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/socket.h>

extern int errno;

#define server_ip   "2001:da8:e000::1:1:89"
#define server_port 3322

#define client_ip "2001:da8:e000::1:1:90"
#define client_port 2233

void errorPrint()
{
        char *errMsg= strerror(errno);
        printf("errno:%d,errorMsg:%s\n",errno,errMsg);
}

int main(void)
{
        struct sockaddr_in6 server;
        struct sockaddr_in6 client;
        int     sock;
        int     val;
        int rc=0;
        char source_ip[40]={0};
        char dest_ip[40]={0};
        short src_port=1111;
        short dest_port=2222;
        char sendbuf[40]={0};
        char recvbuf[1024];
        int send_len=0;
        int recv_len=0;

        memset(&server,0,sizeof(client));
        memset(&client,0,sizeof(client));
        server.sin6_family = AF_INET6;
        client.sin6_family = AF_INET6;
        server.sin6_port = htons(server_port);
        client.sin6_port = htons(client_port);

        rc=inet_pton(AF_INET6,client_ip ,&client.sin6_addr);
        if(rc!=1)
        {
                printf("open_udp_socket_v6 error,inet_pton error!\n";
                return -1;
        }
        rc=inet_pton(AF_INET6,server_ip,&server.sin6_addr);
        if(rc!=1)
        {
                printf("open_udp_socket_v6 error,inet_pton error!\n";
                return -1;
        }

         if((sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0)
         {
                printf("open_udp_socket_v6 error(socket error)\n";
                return -1;
         }

        val = 1;
       /*bind过程中本地地址可重复使用*/
        if(setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val,sizeof(val)) < 0)
         {
                close(sock);
                printf("open_udp_socket_v6 error(setsockopt error)\n";
                return -1;
         }

        if(bind(sock,(struct sockaddr*)&client,sizeof(client)) < 0)
         {
                close(sock);
                printf("open_udp_socket_v6 error(bind error)\n");
                return -1;
         }

        if(connect(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
         {
                errorPrint();
                close(sock);
                printf("open_udp_socket_v6 error(connect error)\n");
                return -1;
         }

        strcpy(sendbuf,"testmess!");
        send_len=strlen(sendbuf);
        rc=sendto(sock,sendbuf,send_len,0,(struct sockaddr*)&server,sizeof(server));
        if(rc!=send_len)
        {
                errorPrint();
                close(sock);
                printf("open_udp_socket_v6 error(sendto error)\n");
                return -1;
        }

/*
        while(1)
        {
                memset(recvbuf,0,sizeof(recvbuf));
                recv_len=recv(sock,recvbuf,1024,0);
                printf("recv_len is %d\n",recv_len);
                if(recv_len==0)
                        continue;
                if(recv_len<0)
                {
                        printf("recv error,errno:%s\n",strerror(errno));
                        continue;
                }
        }
*/

        return 0;
}

目前的问题是:
1.当客户端给服务端发包时候,通过抓包能够看到客户端发来的包,但是程序收不到报文,抓包如下:
  1. 15:38:51.427517 IP6 (hlim 64, next-header UDP (17) payload length: 17) 2001:da8:e000::1:1:90.infocrypt > 2001:da8:e000::1:1:89.3322: [udp sum ok] UDP, length 9
复制代码
PS:如果是客户端,服务端在同一台主机,可以接收到报文
  1. get length:9,message is testmess!
复制代码
2.当客户端放开注释的最后一段recv代码时候,报错:
  1. recv_len is -1
  2. recv error,errno:Permission denied
复制代码






论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
2 [报告]
发表于 2017-04-28 10:04 |只看该作者
看见了EACCES/permission denied所以我脚着是SELinux的问题,你把它禁了再看看。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
3 [报告]
发表于 2017-04-28 17:36 |只看该作者
刚好我这边最近也在测试IPV6,并且已经将新的haisql_memcache开始支持IPv6.  原来代码是IPv4的,然后服务器代码修改了一行listen监听IPv6 port, 发现原来的IPv4的地址仍然可以使用,也就是是说只需要监听IPv6的端口, IPV4的地址和连接都可以不受限制的使用, 不过, 我这边使用的是boost::asio, Debug调试发现本地连接的127.0.0.1地址在内部被转换为::ffffffff:127.0.0.1, 要么楼主测试一下IPV4的使用情况? 看能否发现一点线索。

论坛徽章:
5
金牛座
日期:2015-07-03 13:32:00卯兔
日期:2015-07-03 13:32:17程序设计版块每日发帖之星
日期:2015-11-29 06:20:0015-16赛季CBA联赛之同曦
日期:2015-12-15 09:36:06CU十四周年纪念徽章
日期:2016-07-06 17:18:48
4 [报告]
发表于 2017-05-02 09:10 |只看该作者
回复 2# windoze

禁用了selinux试了,结果和原来一样。还是本地的客户端发送,本地服务端能收到消息。
跨主机的先相同的客户端发送,在服务端抓包已经看到接收到了包,但是服务端程序收不到。
猫大大能帮忙看看程序代码方面有没有什么问题?

PS:好像代码太长,论坛的代码格式贴进去没用。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP