//TCP and UDP can bind to the same IP & port.

#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 1024 int 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; //concern about read event
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 ) );
assert( ret != -1 ); ret = listen( listenfd, 5 );
assert( ret != -1 ); bzero( &address, sizeof( address ) );
address.sin_family = AF_INET;
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 ) );
assert( ret != -1 ); epoll_event events[ MAX_EVENT_NUMBER ];
int epollfd = epoll_create( 5 );
assert( epollfd != -1 );
addfd( epollfd, listenfd );
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 );
if ( connfd < 0 )
{
printf( "errno is: %d\n", errno );
}
else
{
addfd( epollfd, connfd );
char remote[INET_ADDRSTRLEN ];
printf( "connected client ip: %s and port: %d\n",
inet_ntop( AF_INET, &client_address.sin_addr, remote, INET_ADDRSTRLEN ), ntohs( client_address.sin_port ) );
}
}
//UDP is readable
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 (ret == 0)
{
printf("client peer closed().\n");
//shutdown(udpfd); //udp套接字而言shutdown毫无意义
close(udpfd);
}
else
{
printf("UDP recvfrom ran into error: \n", errno);
//handle error....
}
}
//TCP connfd is readable
else if ( events[i].events & EPOLLIN )
{
char buf[ TCP_BUFFER_SIZE ];
while( 1 )
{
memset( buf, '\0', TCP_BUFFER_SIZE );
//sockfd is nonblock
ret = recv( sockfd, buf, TCP_BUFFER_SIZE-1, 0 );
if( ret < 0 )
{
if( ( errno == EAGAIN ) || ( errno == EWOULDBLOCK ) || (errno == EINTR) )
{
break;
}
else
{
printf("TCP recv ran into error, close() socket.\n");
close( sockfd );
break;
}
}
else if( ret == 0 ) //peer called close() and sent a FIN to here
{
printf("TCP recv return 0: peer client close(), so close() self.\n");
close( sockfd );
}
else //normal, send back what we have received! ECHO~
{
send( sockfd, buf, ret, 0 );
}
}
}
else
{
printf( "something else happened \n" );
}
}
} close( listenfd );
return 0;
}

  

linux socket TCP UDP bind 同义IP和port的更多相关文章

  1. 从Linux源码看Socket(TCP)的bind

    从Linux源码看Socket(TCP)的bind 前言 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 今天笔者就来从Linux源码的角度看下Server ...

  2. 27.Socket,TCP,UDP,HTTP基本通信原理

    Socket,TCP,UDP,HTTP基本通信原理(摘自百度): TCP.UDP,HTTP 底层通信都是通过 socket 套接字实现 网络上不同的计算机,也可以通信,那么就得使用网络套接字(sock ...

  3. SOCKET, TCP/UDP, HTTP, FTP 浅析

    SOCKET, TCP/UDP, HTTP, FTP (一)TCP/UDP,SOCKET,HTTP,FTP简析   TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层: 网络层:IP协议. ...

  4. 网络编程之socket(TCP,UDP)

    socket层 tcp协议和udp协议 1)Socket服务器编程 主要包括下面的几步: 1.打开socket 2.绑定到一个地址和端口 3.侦听进来的连接 4.接受连接 5.读写数据 (2)Sock ...

  5. 简单使用SOCKET,TCP,UDP模式之间的通信

    TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机网络OSI模型中, ...

  6. TCP/UDP 、HTTP、IP 、socket 的关系。

    网络有上下分为7 层.物理层,数据链路层.网络层.会话层.应用层.传输层: IP协议位于网络层,IP和端口来控制网络流向: TCP.UDP是基于传输层.TCP保证三次握手.传递数据: UDP为不考虑是 ...

  7. day29 python 套接字socket TCP udp 形式发送信息的区别

    我们经常把socket翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket起源于UNIX,在 ...

  8. iOS socket TCP UDP

    TCP: 服务器: #import <Foundation/Foundation.h> #include <sys/socket.h> #include <netinet ...

  9. 网络编程 套接字socket TCP UDP

    网络编程与套接字 网络编程 网络编程是什么: ​ 网络通常指的是计算机中的互联网,是由多台计算机通过网线或其他媒介相互链接组成的 ​ 编写基于网络的应用程序的过程序称之为网络编程. 网络编程最主要的工 ...

随机推荐

  1. 存储之磁盘阵列RAID

         存储之磁盘阵列RAID RAID是由美国加州大学伯克利分校的D.A. Patterson教授在1988年提出的.RAID名为独立冗余磁盘阵列(RedundantArray of Indepe ...

  2. Linux 抽象网络设备简介

    Linux 抽象网络设备简介 和磁盘设备类似,Linux 用户想要使用网络功能,不能通过直接操作硬件完成,而需要直接或间接的操作一个 Linux 为我们抽象出来的设备,既通用的 Linux 网络设备来 ...

  3. Android sdk安装目录中没有platform-tools目录问题详解

    sdk下载地址 http://tools.android-studio.org/index.php/sdk 安装步骤很简单,百度即可. 下面详细说一下,在安装中遇到android sdk下没有plat ...

  4. 查看nginx | apache | php | tengine | tomcat版本的信息以及如何隐藏版本信息【转】

    转自: 查看nginx | apache | php | tengine | tomcat版本的信息以及如何隐藏版本信息 - 追马 - 51CTO技术博客http://lovelace.blog.51 ...

  5. springcloud服务安全连接

    Spring Cloud可以增加HTTP Basic认证来增加服务连接的安全性. 1.加入security启动器 在maven配置文件中加入Spring Boot的security启动器. <d ...

  6. 八、vue使用element-ui组件

    element-ui组件 1.引入element import Vue from 'vue'; import ElementUI from 'element-ui'; import 'element- ...

  7. ftp配置文件

    vsftpd配置文件采用“#”作为注释符,以“#”开头的行和空白行在解析时将被忽略,其余的行被视为配置命令行,每个配置命令的“=”两边不要留有空格.对于每个配置命令,在配置文件中还列出了相关的配置说明 ...

  8. 浅谈HIbernate

    Hiberbate是面向对象,需要把对象和数据库进行映射.与数据库无关,操作的是对象,会根据数据源和数据库的方言生成对应的sql语句进行查询,是一个优秀的java持久层解决方案,是当今主流的对象-关系 ...

  9. 1.网站应用程序 - 《APS.NET本质论》

    1.1.HTTP协议 浏览器与WEB服务器的协议是应用层协议,当前遵循HTTP/1.1,HTTP协议是无状态的协议 客户机与服务器通过请求和响应完成一次会话(Session),每次会话中,双方发送的数 ...

  10. 事务ACID特性

    所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位.例如,银行转帐工作:从一个帐号扣款并使另一个帐号增款,这两个操作要么都执行,要么都不执行. 数据库事务必须具备 ...