Linux系统下UDP通信过程的C语言实现

需要实现的功能要点如下:

1)通过对等模式实现通信。

2)因为UDP的程序是通过send和recv交替运行的,需要注意阻塞问题。通过Setsockopt,设置阻塞时间;设置read/recv为非阻塞模式。

3)设初值为1,每次+1,直至增加到n。

详细代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


/******************************** Locals ************************************/
int           iUdpSockfd;                 // define server sockfd
static int    iIplength    = 15;          // IP address length
const  int    iMax         = 10;          // set the max number

/******************************** Code **************************************/

/*****************************************************************************
* Function   : KillHandle
* Description: receive the ctrl+c, and close the parent's socket and exit proc
* Parameter  :
* Return     : void
* Explain    : NO
******************************************************************************/
void KillHandle()
{
    close (iUdpSockfd);
    printf("%d kill me (SIGINT,SIGTERM).\n", getpid());
    exit  (0);
}
/******************************************************************************
* Function    : main
* Description : work as server: receive a number, send number++
* Parameter   : IN  int arg:
*                     number of parameters in command line
*                   char * argv[]:
*                     First address of the string in command line
*                   char ** evniron:
*                     Environment variable
* Return      : The operation result.
*                0 : run and exit normally.
*               !0 : run adn exit abnormally.
* Explain     : use UDP socket 一个程序完成stUdpAddress和stUdpAddress2 之间的收发,
 只要只命令行出入命令的时候开两个终端,将对方的端口号和自己的端口号调换就行了。
******************************************************************************/
int main(int arg, char * argv[], char ** evniron)
{
    struct    sockaddr_in  stUdpAddress;    // self  addr struct
    struct    sockaddr_in  stUdpAddress2;   // other addr struct
    char      cIpaddrSelf[iIplength+1]  ;   // self  IP addr
    char      cIpaddrOther[iIplength+1] ;   // other IP addr

    int       iUdpLen;               // these sockaddr_in length
    int       iPort1   = 9734;       // default selfport value
    int       iPort2   = 9735;       // default other    value
    int       iExit    = 1;          // exit identifier
    int       iReturn  = 0;          // record some function return
    int       i        = 1;          // init value
    int       iError   = 0;          // record the times of failing to recvfrom()

    struct    timeval  stRecvto;     // define a time struct for set setsockopt()
    int       iTolen   = sizeof(struct timeval);
    stRecvto.tv_sec    = 3;          // wait time
    stRecvto.tv_usec   = 0;
    // initialise char array
    memset(cIpaddrSelf,  '\0', sizeof(cIpaddrSelf ));
    memset(cIpaddrOther, '\0', sizeof(cIpaddrOther));
    // initialise it's original value is "127.0.0.1"
    strcpy(cIpaddrSelf,  "127.0.0.1");
    strcpy(cIpaddrOther, "127.0.0.1");

    printf("--------------------- UDP socket begin-----------------------\n\n");
    // get conmand from the conmand lane
    while ((iReturn = getopt(arg, argv, "p:q:a:b:")) != EOF)
    {
        switch (iReturn)
        {
            case 'p':    // self  port
                iPort1 = atoi(optarg);//optarg 是getopt的一个参数,表示-p后个那个命令行参数放到iPort1中
                break;
            case 'q':    // other port
                iPort2 = atoi(optarg);
                break;
           /* case 'a':    // self  IP address
                strcpy(cIpaddrSelf, optarg);
                break;*/
            case 'b':    // other Ip address
                strcpy(cIpaddrOther, optarg);
                break;
            default:
                perror("error comand!\n");
                perror("it will use the default value!\n");
                break;
        }
    }

    //printf(" selfport = %5d,  self IP = %s.\n", iPort1, cIpaddrSelf );
    printf("otherport = %5d, other IP = %s.\n", iPort2, cIpaddrOther);
    // create UDP socket
    iUdpSockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (-1 == iUdpSockfd)
    {
        perror("create socket failed!\n");
        exit(1);
    }
    //initalize socket struct: self;
    stUdpAddress.sin_family       = AF_INET;
    stUdpAddress.sin_addr.s_addr  = inet_addr(cIpaddrSelf);   // IP
    stUdpAddress.sin_port         = htons(iPort1);            // port
    //initalize socket struct: other;
    stUdpAddress2.sin_family      = AF_INET;
    stUdpAddress2.sin_addr.s_addr = inet_addr(cIpaddrOther);  // IP
    stUdpAddress2.sin_port        = htons(iPort2);            // port

    iUdpLen = sizeof(stUdpAddress);
    // when press ^c, it will emit SIGINT;
    signal(SIGINT, KillHandle);
    // bind the iUdpSockfd to the stUdpAddress
    if (-1 == bind(iUdpSockfd, (struct sockaddr *)&stUdpAddress, iUdpLen))
    {
        perror("bind failed!\n");
        close (iUdpSockfd);
        exit  (1);
    }
    // set the function: recvfrom() waiting time
    setsockopt(iUdpSockfd, SOL_SOCKET, SO_RCVTIMEO, &stRecvto, iTolen);

    while (i < iMax)
    {
        // send i to stUdpAddress2
        iReturn = sendto(iUdpSockfd, &i, sizeof(i), 0,
                  (struct sockaddr *) &stUdpAddress2, sizeof(stUdpAddress2));
        if (-1 == iReturn)
        {
            perror("sendto failed!\n");
            break;
        }
        sleep(1);
        // receive i from stUdpAddress
        iReturn = recvfrom(iUdpSockfd, &i, sizeof(i), 0,
                  (struct sockaddr *) &stUdpAddress, &iUdpLen);
        i++;
        if (iReturn != -1)
        {
            printf("received i = %d.\n", i);
        }
        else
        {
            break;
        }
    }

    if (i == iMax)
    {
        printf("--------------------successful transfer!---------------------\n");
    }
    else
    {
        printf("-----------------error happened in transfer!-----------------\n");
    }
    // close the UPD socket
    iReturn = close(iUdpSockfd);
    if (-1 == iReturn)
    {
        perror("Fail to close socket.\n");
        exit(1);
    }
    exit(0);
}

 

你可能感兴趣的:(C/C++)