在adhoc网络上的C程序之间的通信

时间:2012-10-14 16:05:03

标签: c sockets network-programming multicast multicastsocket

我有以下服务器代码

    #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>


#define HELLO_PORT 12345
#define HELLO_GROUP "255.0.0.37"

main(int argc, char *argv[])
{
    struct sockaddr_in addr;
        struct sockaddr_in client,server;
        int s,n;
        char index;
    int f; 
        char b1[100];
        int fd, cnt,i=0;;
        struct ip_mreq mreq;
        //char *message="Hello, World!";
    char *message=NULL;
        /* create what looks like an ordinary UDP socket */
        if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) 
    {
        perror("socket");
        exit(1);
        }
        s=socket(AF_INET,SOCK_DGRAM,0);
        server.sin_family=AF_INET;
        server.sin_port=2000;
        server.sin_addr.s_addr=inet_addr("10.42.0.47");
        bind(s,(struct sockaddr *)&server,sizeof(server));
        printf("\nServer ready,waiting for client....\n");
        n=sizeof(client);
        /* set up destination address */
        memset(&addr,0,sizeof(addr));
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=inet_addr(HELLO_GROUP);
        addr.sin_port=htons(HELLO_PORT);

        /* now just sendto() our destination! */
        while (1) 
        {
        recvfrom(s,b1,sizeof(b1),0,(struct sockaddr *) &client,&n);
        printf("client : %s\n",b1);
        //sleep(5);
        index=b1[0];
        f=b1[0];
        //printf("b1[1] is %c\n",index);
        //printf("b1[0] is %c\n",f);
        f=32;
        b1[0]=f;
        //printf("new b1[0] is %c\n",b1[0]);
        //printf("%s\n",b1);
        if(index!='C')
        {
            if (sendto(fd,b1,sizeof(b1),0,(struct sockaddr *) &addr,sizeof(addr)) < 0)
            {
                    perror("sendto");
                    exit(1);
            }
            //i++;
            /*if(i>=4)
            {
                i=0;
            }*/
            sleep(1);
        }
        }
}

以下客户端代码在不同的系统上运行

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdio.h> 
#include <mysql.h>

#define HELLO_PORT 12345
#define HELLO_GROUP "225.0.0.37"
#define MSGBUFSIZE 1024

main(int argc, char *argv[])
{
    MYSQL mysql; 
    MYSQL_ROW row; 
    MYSQL_RES *result; 
        unsigned int num_fields; 
    unsigned int i; 
    mysql_init(&mysql); 
        struct sockaddr_in server;
        int s,n;
    char b1[100],b2[100],a[100];
    char re[100]={0};
    char g=" ";
    printf("%c\n",re);
    strcpy(b2,"1");
    char message[20],ch='n';
        struct sockaddr_in addr;
        int fd, nbytes,addrlen,j=0;
        struct ip_mreq mreq;
        char msgbuf[MSGBUFSIZE];
        u_int yes=1;            /*** MODIFICATION TO ORIGINAL */

     /* create what looks like an ordinary UDP socket */
        if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) 
    {
        perror("socket");
        exit(1);
        }
    s=socket(AF_INET,SOCK_DGRAM,0);
        server.sin_family=AF_INET;
        server.sin_port=2000;
        server.sin_addr.s_addr=inet_addr("10.42.0.1");
        printf("\nClient ready....\n");
        n=sizeof(server);

    if (!mysql_real_connect(&mysql,"localhost","root","nidhi","project",0,NULL,0)) 
    {    
            fprintf(stderr, "Failed to connect to database: Error: %s\n", 
            mysql_error(&mysql)); 
    } 
    /**** MODIFICATION TO ORIGINAL */
        /* allow multiple sockets to use the same PORT number */
        if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) 
    {
            perror("Reusing ADDR failed");
            exit(1);
        }
    /*** END OF MODIFICATION TO ORIGINAL */
        /* set up destination address */
        memset(&addr,0,sizeof(addr));
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */
        addr.sin_port=htons(HELLO_PORT);  
        /* bind to receive address */
        if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) 
    {
        perror("bind");
        exit(1);
        }

        /* use setsockopt() to request that the kernel join a multicast group */
        mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP);
        mreq.imr_interface.s_addr=htonl(INADDR_ANY);
        if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) 
    {
        perror("setsockopt");
        exit(1);
        }

        /* now just enter a read-print loop */
        while (1) 
    {
        /*if ((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0,(struct sockaddr *) &addr,&addrlen)) < 0) 
        {
                perror("recvfrom");
                exit(1);
        }
        printf("the server says: %s\n",msgbuf);*/
        printf("would you like to send?(y/n)\n");
        scanf("%c",&ch);
        fflush(stdin);
        if(ch=='y')
        {
        printf("\nClient:");
            gets(a);
        printf("%c\n",a);
        strcat(b2,a);
        printf("%s\n",b2);
            sendto(s,b2,sizeof(b2),0,(struct sockaddr *) &server,n);
        b2[100]=NULL;
        strcpy(b2,"1");
        }
        addrlen=sizeof(addr);
        if ((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0,(struct sockaddr *) &addr,&addrlen)) < 0) 
        {
                perror("recvfrom");
                exit(1);
        }
        printf("the server says: %s\n",msgbuf);
        if(mysql_query(&mysql,msgbuf));
        else
        {
            strcpy(re,"Client 1: ");
            sendto(s,re,sizeof(re),0,(struct sockaddr *) &server,n);
            //printf("inside else case\n");
            result=mysql_store_result(&mysql);
            //printf("\n after getting the result...\n");
            num_fields = mysql_num_fields(result); 
            //printf("\n after getting numfields...\n");
                while ((row = mysql_fetch_row(result))) 
                {    
                        unsigned long *lengths; 
                //printf("\n inside while....\n");
                        lengths = mysql_fetch_lengths(result); 
                        for(i = 0; i < num_fields; i++) 
                        { 
                                printf("[%.*s] \t", (int) lengths[i], row[i] ? row[i] : "NULL"); 
                    strcat(re,row[i]);
                    j++;
                    //printf("%d\n",j);
                    if(j==4)
                    {
                        //printf("the result is .....%s\n",re);
                        sendto(s,re,sizeof(re),0,(struct sockaddr *) &server,n);
                        memset(re,0,100);
                        strcpy(re,"Client 1: ");
                        j=0;
                    }

                        }    
                        printf("\n"); 
                } 
            } 
    }
}

我创建了一个adhoc网络,并为服务器和客户端分配了两个ip地址。 10.42.0.1/24到服务器,10.42.0.47 / 24到客户端

然而,从客户端到服务器的单播操作无法正常运行,也不是从服务器到客户端的多播。

其次,我如何确定这两个程序是否属于同一个多播组。客户端上的错误是

  

setsockopt:无效参数

  

setsockopt:没有这样的设备

对此有任何帮助,非常感谢.. !!

1 个答案:

答案 0 :(得分:1)

您的代码中存在许多潜在错误:

服务器:

1.您没有检查's'套接字是否已成功创建。但是,您的示例将在没有它的情况下工作,因为有足够的内存用于创建套接字。

2.你没有检查bind()的返回码,也许你不能将套接字绑定到端口,这就是你得到'无效参数'错误的原因

3.您没有检查recvfrom()....

的返回码

4. IP 255.0.0.37保留供将来使用,我不确定它是否有效,为什么不使用有效的IP范围?

5.对于多播,您必须使用范围内的IP地址:224.0.0.0/4,而不是10.0.0.0/8,因为它是为本地网络保留的。

关于客户端,您应首先制作udp协议代码,然后将mysql添加到其中。您还必须告诉我们您遇到错误的哪一行,否则很难分析问题。