第九章 TCP和UDP同時用複用一個連接埠實現一個回射伺服器

來源:互聯網
上載者:User

標籤:linux伺服器編程




#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <assert.h>#include <stdio.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <fcntl.h>#include <stdlib.h>#include <sys/epoll.h>#include <pthread.h>#define MAX_EVENT_NUMBER 1024#define TCP_BUFFER_SIZE 512#define UDP_BUFFER_SIZE 1024int setnonblocking( int fd ){    int old_option = fcntl( fd, F_GETFL );    int new_option = old_option | O_NONBLOCK;    fcntl( fd, F_SETFL, new_option );    return old_option;}void addfd( int epollfd, int fd ){    epoll_event event;    event.data.fd = fd;    //event.events = EPOLLIN | EPOLLET;    event.events = EPOLLIN;    epoll_ctl( epollfd, EPOLL_CTL_ADD, fd, &event );    setnonblocking( fd );}int main( int argc, char* argv[] ){    if( argc <= 2 )    {        printf( "usage: %s ip_address port_number\n", basename( argv[0] ) );        return 1;    }    const char* ip = argv[1];    int port = atoi( argv[2] );    int ret = 0;    struct sockaddr_in address;    bzero( &address, sizeof( address ) );    address.sin_family = AF_INET;    inet_pton( AF_INET, ip, &address.sin_addr );    address.sin_port = htons( port );    int listenfd = socket( PF_INET, SOCK_STREAM, 0 );    assert( listenfd >= 0 );    ret = bind( listenfd, ( struct sockaddr* )&address, sizeof( address ) );//TCP串連檔案描述符listenfd和address綁定了    assert( ret != -1 );    ret = listen( listenfd, 5 );    assert( ret != -1 );    bzero( &address, sizeof( address ) );//清空了address    address.sin_family = AF_INET;//重新設定address為udp伺服器端地址資訊    inet_pton( AF_INET, ip, &address.sin_addr );    address.sin_port = htons( port );    int udpfd = socket( PF_INET, SOCK_DGRAM, 0 );    assert( udpfd >= 0 );    ret = bind( udpfd, ( struct sockaddr* )&address, sizeof( address ) );//UDP串連檔案描述符udpfd和address綁定了    assert( ret != -1 );//同一個連接埠上綁定了兩個不同類型(TCP和UDP)的socket檔案描述符//建立epoll事件監聽模型    epoll_event events[ MAX_EVENT_NUMBER ];    int epollfd = epoll_create( 5 );    assert( epollfd != -1 );    addfd( epollfd, listenfd );//listenfd和udpfd均註冊到核心註冊表epollfd上    addfd( epollfd, udpfd );    while( 1 )    {        int number = epoll_wait( epollfd, events, MAX_EVENT_NUMBER, -1 );        if ( number < 0 )        {            printf( "epoll failure\n" );            break;        }            for ( int i = 0; i < number; i++ )        {            int sockfd = events[i].data.fd;            if ( sockfd == listenfd )            {                struct sockaddr_in client_address;                socklen_t client_addrlength = sizeof( client_address );                int connfd = accept( listenfd, ( struct sockaddr* )&client_address, &client_addrlength );                addfd( epollfd, connfd );            }            else if ( sockfd == udpfd )            {                char buf[ UDP_BUFFER_SIZE ];                memset( buf, '\0', UDP_BUFFER_SIZE );                struct sockaddr_in client_address;                socklen_t client_addrlength = sizeof( client_address );                ret = recvfrom( udpfd, buf, UDP_BUFFER_SIZE-1, 0, ( struct sockaddr* )&client_address, &client_addrlength );                if( ret > 0 )                {                    sendto( udpfd, buf, UDP_BUFFER_SIZE-1, 0, ( struct sockaddr* )&client_address, client_addrlength );                }            }            else if ( events[i].events & EPOLLIN )            {                char buf[ TCP_BUFFER_SIZE ];                while( 1 )                {                    memset( buf, '\0', TCP_BUFFER_SIZE );                    ret = recv( sockfd, buf, TCP_BUFFER_SIZE-1, 0 );                    if( ret < 0 )                    {                        if( ( errno == EAGAIN ) || ( errno == EWOULDBLOCK ) )                        {                            break;                        }                        close( sockfd );                        break;                    }                    else if( ret == 0 )                    {                        close( sockfd );                    }                    else                    {                        send( sockfd, buf, ret, 0 );                    }                }            }            else            {                printf( "something else happened \n" );            }        }    }    close( listenfd );    return 0;}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.