分享

select在udp里面使用双端口接收

 wusiqi111 2017-12-07
服务端:

/************SERVER**************/


#include<stdio.h>

#include<time.h>

#include<stdlib.h>

#include<sys/socket.h>

#include<sys/types.h>

#include<netinet/in.h>

#include<netdb.h>

#include<string.h>


#define PORT_A  11111

#define PORT_B  22222


int main(int argc, char **argv)

{

 

    int socka;   // 套接口a

    int sockb;   // 套接口b

    

    int nPortA = PORT_A;

    int nPortB = PORT_B;

    fd_set rfd;     // 读描述符集

    struct timeval timeout;    // 定时变量

    struct sockaddr_in addr; // 告诉sock 应该在什么地方licence

    char recv_buf[1024];    // 接收缓冲区

    

    int nRecLen; // 客户端地址长度!!!!!!

    int fdmax = -1;

    

    struct sockaddr_in cli;    // 客户端地址

    int nRet; // select返回值


    socka = socket(AF_INET, SOCK_DGRAM, 0); // 创建数据报socka

    if (socka < 0)

    {

        printf("socket()\n");

        return 0;

    }

    sockb = socket(AF_INET, SOCK_DGRAM, 0); // 创建数据报sockb

    if (sockb < 0)

    {

        printf("socket()\n");

        return 0;

    }

    memset(&addr, 0, sizeof(addr));

    

    addr.sin_family = AF_INET;   // IP协议

    addr.sin_port = htons(nPortA); // 端口

    addr.sin_addr.s_addr = htonl(INADDR_ANY); // 在本机的所有ip上开始监听

    if (bind(socka, (struct sockaddr*)&addr, sizeof(addr)) < 0)// bind socka

    {

        printf("bind()\n");

        return 0;

    }

    

    memset(&addr, 0, sizeof(addr));

    addr.sin_family = AF_INET;   // IP协议

    addr.sin_port = htons(nPortB); // 端口

    addr.sin_addr.s_addr = htonl(INADDR_ANY); // 在本机的所有ip上开始监听

    

    if (bind(sockb, (struct sockaddr*)&addr, sizeof(addr)) < 0) // bind sockb

    {

        printf("bind()\n");

        return 0;

    }

    // 设置超时时间为6s

    timeout.tv_sec = 6;

    timeout.tv_usec = 0;

    

    if(sockb>socka)

        fdmax = sockb + 1;

    else

        fdmax = socka + 1;

    memset(recv_buf, 0, sizeof(recv_buf)); // 清空接收缓冲区

    while (1)

    {

        FD_ZERO(&rfd); // 在使用之前总是要清空

        

        // 开始使用select

        FD_SET(socka, &rfd); // socka放入要测试的描述符集中

        FD_SET(sockb, &rfd); // sockb放入要测试的描述符集中

        

        nRet = select(fdmax, &rfd, NULL, NULL, &timeout);// 检测是否有套接口是否可读

        if (nRet < 0)

        {

            printf("select()\n");

            return 0;

        }

        else if (nRet == 0) // 超时

        {

            printf("timeout\n");

            close(socka);

            close(sockb);

            break;

        }

        else    // 检测到有套接口可读

        {

            if (FD_ISSET(socka, &rfd))  // socka可读

            {

                nRecLen = sizeof(cli);

                int nRecEcho = recvfrom(socka, recv_buf, sizeof(recv_buf), 0, (struct sockaddr*)&cli, &nRecLen);

                if (nRecEcho < 0)

                {

                    printf("recvfrom()\n");

                    break;

                }

                printf("data to port 11111: %s\n", recv_buf);

            }

            if (FD_ISSET(sockb, &rfd)) // sockb 可读

            {

                nRecLen = sizeof(cli);

                int nRecEcho = recvfrom(sockb, recv_buf, sizeof(recv_buf), 0, (struct sockaddr*)&cli, &nRecLen);

                if (nRecEcho < 0)

                {

                    printf("recvfrom()\n");

                    break;

                }

                printf("data to port 22222: %s\n", recv_buf);

            }

        }

    }

    

}


客户端:

#include<stdio.h>

#include<time.h>

#include<stdlib.h>

#include<sys/socket.h>

#include<sys/types.h>

#include<netinet/in.h>

#include<netdb.h>

#include<string.h>


#define SERVER_PORT_A 11111     // 服务器端口A

#define SERVER_PORT_B 22222     // 服务器端口B

typedef struct tagSERVER    // 服务器

{

    //char* ip;   // ip地址

    char ip[64];

    int nPort;  // 端口号

} SERVER, *PSERVER;

int SendData(int s, char *ip, int nPort, char *pData); // 发送数据到IP:nPort

int main(int argc, char **argv)

{

    int i;

    int sClient;         // 客户端套接口

    char send_buf[] = "hello! I am LiangFei whoes SNO=06060734";    // 发送的数据内容

    int nSend; // 发送数据后的返回值

    // 服务器

    SERVER sers[] = {   {"127.0.0.1", SERVER_PORT_A},

        {"127.0.0.1", SERVER_PORT_B} };

    int nSerCount = sizeof(sers) / sizeof(sers[0]); // 服务器个数


    

    // 建立客户端数据包套接口

    sClient = socket(AF_INET, SOCK_DGRAM, 0);

    if (sClient < 0)

    {

        printf("socket()\n");

        return 0;

    }

    for (i = 0; i < nSerCount; i++)

    {

        nSend = SendData(sClient, sers[i].ip, sers[i].nPort, send_buf); // 发送数据

        if (nSend == 0) // 发送失败

        {

            return 0;

        }

        else if (nSend < 0) // 套接口出错

        {

            printf("sendto()\n");

            return 0;

        }

    }

    close(sClient);   // 关闭套接口

    return 0;

}

int SendData( int s, char *ip, int nPort, char *pData)

{

    struct sockaddr_in ser;    // 服务器端地址

    ser.sin_family = AF_INET;   // IP协议

    ser.sin_port = htons(nPort);    // 端口号

    ser.sin_addr.s_addr = inet_addr(ip);    // IP地址

    int nLen = sizeof(ser); // 服务器地址长度

    

    return sendto(s, pData, strlen(pData) + 1, 0, (struct sockaddr*)&ser, nLen);   // 向服务器发送数据

}


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约