linux socket编程示例
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <signal.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <assert.h>
- #include <stdio.h>
- #include <string.h>
- static bool stop = false;
- static void handle_term( int sig ) // kill pid; in another tty will triggle this signal
- {
- stop = true;
- printf("signal SIGTERM catched...\n");
- }
- static void handle_int(int sig) // ctrl+c; will triggle this signal
- {
- printf("signal SIGINT catched...\n");
- stop = true;
- }
- //./listen 127.0.0.1 8888 100
- int main( int argc, char* argv[] )
- {
- signal( SIGTERM, handle_term );
- signal(SIGINT, handle_int);
- if( argc <= 3 )
- {
- printf( "usage: %s ip_address port_number backlog\n", basename( argv[0] ) );
- return 1;
- }
- const char* ip = argv[1];
- int port = atoi( argv[2] );
- int backlog = atoi( argv[3] );
- int sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 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 ret = bind( sock, ( struct sockaddr* )&address, sizeof( address ) );
- assert( ret != -1 );
- printf("after bind...\n");
- //backlog is the max number of waitting connect in wait queue
- ret = listen( sock, backlog ); //listen is a none-block function
- assert( ret != -1 );
- printf("after listen...\n");
- while ( ! stop )
- {
- sleep( 1 );
- }
- close( sock );
- return 0;
- }
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- 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] );
- 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 sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 0 );
- int reuse = 1;
- setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof( reuse ) );
- int ret = bind( sock, ( struct sockaddr* )&address, sizeof( address ) );
- assert( ret != -1 );
- printf("AFTER bind...\n");
- ret = listen( sock, 5 );
- assert( ret != -1 );
- printf("AFTER listen...\n");
- //the returned client is client's address
- struct sockaddr_in client;
- socklen_t client_addrlength = sizeof( client );
- int connfd = accept( sock, ( struct sockaddr* )&client, &client_addrlength ); //accept is a block function
- printf("AFTER accept...\n");
- if ( connfd < 0 )
- {
- printf( "errno is: %d\n", errno );
- }
- else
- {
- //#define INET_ADDRSTRLEN 16 , IPV4 address char array length, <netinet/in.h>
- char remote[INET_ADDRSTRLEN ];
- printf( "connected with ip: %s and port: %d\n",
- inet_ntop( AF_INET, &client.sin_addr, remote, INET_ADDRSTRLEN ), ntohs( client.sin_port ) );
- close( connfd );
- }
- close( sock );
- return 0;
- }
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #define BUF_SIZE 1024
- 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] );
- 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 sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 0 );
- int ret = bind( sock, ( struct sockaddr* )&address, sizeof( address ) );
- assert( ret != -1 );
- ret = listen( sock, 5 );
- assert( ret != -1 );
- printf("after listen...\n");
- struct sockaddr_in client;
- socklen_t client_addrlength = sizeof( client );
- int connfd = accept( sock, ( struct sockaddr* )&client, &client_addrlength );
- printf("after accept...\n");
- if ( connfd < 0 )
- {
- printf( "errno is: %d\n", errno );
- }
- else
- {
- char buffer[ BUF_SIZE ];
- memset( buffer, '\0', BUF_SIZE );
- ret = recv( connfd, buffer, BUF_SIZE-1, 0 );
- printf( "got %d bytes of normal data '%s'\n", ret, buffer );
- memset( buffer, '\0', BUF_SIZE );
- //MSG_OOB: support recv out-of-band data
- //Only TCP support oob data
- //TCP only 1 byte oob data
- //use MSG_OOB flag when call send to send oob data
- ret = recv( connfd, buffer, BUF_SIZE-1, MSG_OOB );
- printf( "got %d bytes of oob data '%s'\n", ret, buffer );
- memset( buffer, '\0', BUF_SIZE );
- ret = recv( connfd, buffer, BUF_SIZE-1, 0 );
- printf( "got %d bytes of normal data '%s'\n", ret, buffer );
- close( connfd );
- }
- close( sock );
- return 0;
- }
connect
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #define BUFFER_SIZE 512
- int main( int argc, char* argv[] )
- {
- if( argc <= 3 )
- {
- printf( "usage: %s ip_address port_number send_bufer_size\n", basename( argv[0] ) );
- return 1;
- }
- const char* ip = argv[1];
- int port = atoi( argv[2] );
- struct sockaddr_in server_address;
- bzero( &server_address, sizeof( server_address ) );
- server_address.sin_family = AF_INET;
- inet_pton( AF_INET, ip, &server_address.sin_addr );
- server_address.sin_port = htons( port );
- int sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 0 );
- int sendbuf = atoi( argv[3] );
- int len = sizeof( sendbuf );
- setsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, sizeof( sendbuf ) );
- getsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, ( socklen_t* )&len );
- printf( "the tcp send buffer size after setting is %d\n", sendbuf );
- if ( connect( sock, ( struct sockaddr* )&server_address, sizeof( server_address ) ) != -1 )
- {
- //
- printf("call getsockname ...\n");
- struct sockaddr_in local_address;
- socklen_t length;
- int ret = getpeername(sock, ( struct sockaddr* )&local_address, &length);
- assert(ret == 0);
- char local[INET_ADDRSTRLEN ];
- printf( "local with ip: %s and port: %d\n",
- inet_ntop( AF_INET, &local_address.sin_addr, local, INET_ADDRSTRLEN ), ntohs( local_address.sin_port ) );
- //
- char buffer[ BUFFER_SIZE ];
- memset( buffer, 'a', BUFFER_SIZE );
- send( sock, buffer, BUFFER_SIZE, 0 );
- }
- close( sock );
- return 0;
- }
accept:
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- 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] );
- 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 sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 0 );
- int reuse = 1;
- setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof( reuse ) );
- int ret = bind( sock, ( struct sockaddr* )&address, sizeof( address ) );
- assert( ret != -1 );
- printf("AFTER bind...\n");
- ret = listen( sock, 5 );
- assert( ret != -1 );
- printf("AFTER listen...\n");
- //the returned client is client's address
- struct sockaddr_in client;
- socklen_t client_addrlength = sizeof( client );
- int connfd = accept( sock, ( struct sockaddr* )&client, &client_addrlength ); //accept is a block function
- printf("AFTER accept...\n");
- if ( connfd < 0 )
- {
- printf( "errno is: %d\n", errno );
- }
- else
- {
- //#define INET_ADDRSTRLEN 16 , IPV4 address char array length, <netinet/in.h>
- char remote[INET_ADDRSTRLEN ];
- printf( "connected with ip: %s and port: %d\n",
- inet_ntop( AF_INET, &client.sin_addr, remote, INET_ADDRSTRLEN ), ntohs( client.sin_port ) );
- //
- printf("call getsockname ...\n");
- struct sockaddr_in local_address;
- socklen_t length;
- int ret = getsockname(connfd, ( struct sockaddr* )&local_address, &length);
- if (ret == 0)
- {
- char local[INET_ADDRSTRLEN ];
- printf( "local connfd ip: %s and port: %d\n", inet_ntop( AF_INET, &local_address.sin_addr, local, INET_ADDRSTRLEN ), ntohs( local_address.sin_port ) );
- }
- else
- printf("getsockname on connfd fail...\n");
- bzero( &local_address, sizeof( local_address ) );
- ret = getpeername(connfd, ( struct sockaddr* )&local_address, &length);
- if (ret == 0)
- {
- char local1[INET_ADDRSTRLEN ];
- printf( "remote ip: %s and port: %d\n", inet_ntop( AF_INET, &local_address.sin_addr, local1, INET_ADDRSTRLEN ), ntohs( local_address.sin_port ) );
- }
- else
- printf("getpeername on connfd fail...\n");
- close( connfd );
- }
- close( sock );
- return 0;
- }
setsendbuffer:
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #define BUFFER_SIZE 512
- int main( int argc, char* argv[] )
- {
- if( argc <= 3 )
- {
- printf( "usage: %s ip_address port_number send_bufer_size\n", basename( argv[0] ) );
- return 1;
- }
- const char* ip = argv[1];
- int port = atoi( argv[2] );
- struct sockaddr_in server_address;
- bzero( &server_address, sizeof( server_address ) );
- server_address.sin_family = AF_INET;
- inet_pton( AF_INET, ip, &server_address.sin_addr );
- server_address.sin_port = htons( port );
- int sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 0 );
- int sendbuf = atoi( argv[3] );
- int len = sizeof( sendbuf );
- setsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, sizeof( sendbuf ) );
- getsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, ( socklen_t* )&len );
- printf( "the tcp send buffer size after setting is %d\n", sendbuf );
- if ( connect( sock, ( struct sockaddr* )&server_address, sizeof( server_address ) ) != -1 )
- {
- char buffer[ BUFFER_SIZE ];
- memset( buffer, 'a', BUFFER_SIZE );
- send( sock, buffer, BUFFER_SIZE, 0 );
- }
- close( sock );
- return 0;
- }
setrecvbuffer:
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #define BUFFER_SIZE 1024
- int main( int argc, char* argv[] )
- {
- if( argc <= 3 )
- {
- printf( "usage: %s ip_address port_number receive_buffer_size\n", basename( argv[0] ) );
- return 1;
- }
- const char* ip = argv[1];
- int port = atoi( argv[2] );
- 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 sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 0 );
- int recvbuf = atoi( argv[3] );
- printf("recvbuf is %d\n", recvbuf); /////!!!
- int len = sizeof( recvbuf );
- printf("len is %d\n", len); /////!!!
- setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, sizeof( recvbuf ) );
- getsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, ( socklen_t* )&len );
- printf( "the receive buffer size after settting is %d\n", recvbuf );
- int ret = bind( sock, ( struct sockaddr* )&address, sizeof( address ) );
- assert( ret != -1 );
- ret = listen( sock, 5 );
- assert( ret != -1 );
- struct sockaddr_in client;
- socklen_t client_addrlength = sizeof( client );
- int connfd = accept( sock, ( struct sockaddr* )&client, &client_addrlength );
- if ( connfd < 0 )
- {
- printf( "errno is: %d\n", errno );
- }
- else
- {
- char buffer[ BUFFER_SIZE ];
- memset( buffer, '\0', BUFFER_SIZE );
- while( recv( connfd, buffer, BUFFER_SIZE-1, 0 ) > 0 )
- {
- printf("%s\n", buffer);
- }
- close( connfd );
- }
- close( sock );
- return 0;
- }
daytime:
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <assert.h>
- #include <errno.h>
- int main( int argc, char *argv[] )
- {
- //assert( argc == 2 );
- //char *host = argv[1];
- struct hostent *host; //存放主机信息
- //char addr_p[NET_ADDR_STR_LEN]; //用于存放点分十进制IP地址的字符串
- if((host = gethostent()) == NULL)
- {
- perror("fail to get host's information\n");
- return -1;
- }
- printf("hostName: %s\n" , host->h_name);
- //用域名或主机名获取IP地址
- struct hostent* hostinfo = gethostbyname( host->h_name );
- assert( hostinfo );
- struct servent* servinfo = getservbyname( "daytime", "tcp" );
- assert( servinfo );
- printf( "daytime port is %d\n", ntohs( servinfo->s_port ) );
- struct sockaddr_in address;
- address.sin_family = AF_INET;
- address.sin_port = servinfo->s_port;
- address.sin_addr = *( struct in_addr* )*hostinfo->h_addr_list;
- char remote[INET_ADDRSTRLEN ];
- printf( "connected with ip: %s and port: %d\n",
- inet_ntop( AF_INET, &address.sin_addr, remote, INET_ADDRSTRLEN ), ntohs( address.sin_port ) );
- int sockfd = socket( AF_INET, SOCK_STREAM, 0 );
- //int reuse = 1;
- //setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof( reuse ) );
- int result = connect( sockfd, (struct sockaddr* )&address, sizeof( address ) );
- printf( "errno is: %d\n", errno );
- perror("connect error:");
- assert( result != -1 );
- char buffer[128];
- result = read( sockfd, buffer, sizeof( buffer ) );
- assert( result > 0 );
- buffer[ result ] = '\0';
- printf( "the day tiem is: %s", buffer );
- close( sockfd );
- return 0;
- }
testdup:
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- 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] );
- 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 sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 0 );
- int ret = bind( sock, ( struct sockaddr* )&address, sizeof( address ) );
- assert( ret != -1 );
- ret = listen( sock, 5 );
- assert( ret != -1 );
- struct sockaddr_in client;
- socklen_t client_addrlength = sizeof( client );
- int connfd = accept( sock, ( struct sockaddr* )&client, &client_addrlength );
- if ( connfd < 0 )
- {
- printf( "errno is: %d\n", errno );
- }
- else
- {
- close( STDOUT_FILENO );
- dup( connfd );
- printf( "abcd\n" ); //the same as write/send data in connfd
- close( connfd );
- }
- close( sock );
- return 0;
- }
writev:
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #define BUFFER_SIZE 1024
- static const char* status_line[2] = { "200 OK", "500 Internal server error" };
- int main( int argc, char* argv[] )
- {
- if( argc <= 3 )
- {
- printf( "usage: %s ip_address port_number filename\n", basename( argv[0] ) );
- return 1;
- }
- const char* ip = argv[1];
- int port = atoi( argv[2] );
- const char* file_name = argv[3];
- 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 sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 0 );
- int ret = bind( sock, ( struct sockaddr* )&address, sizeof( address ) );
- assert( ret != -1 );
- ret = listen( sock, 5 );
- assert( ret != -1 );
- struct sockaddr_in client;
- socklen_t client_addrlength = sizeof( client );
- int connfd = accept( sock, ( struct sockaddr* )&client, &client_addrlength );
- if ( connfd < 0 )
- {
- printf( "errno is: %d\n", errno );
- }
- else
- {
- char header_buf[ BUFFER_SIZE ];
- memset( header_buf, '\0', BUFFER_SIZE );
- char* file_buf;
- struct stat file_stat;
- bool valid = true;
- int len = 0;
- if( stat( file_name, &file_stat ) < 0 )
- {
- valid = false;
- }
- else
- {
- if( S_ISDIR( file_stat.st_mode ) )
- {
- valid = false;
- }
- else if( file_stat.st_mode & S_IROTH )
- {
- int fd = open( file_name, O_RDONLY );
- file_buf = new char[ file_stat.st_size + 1 ];
- memset( file_buf, '\0', file_stat.st_size + 1 );
- if ( read( fd, file_buf, file_stat.st_size ) < 0 )
- {
- valid = false;
- }
- }
- else
- {
- valid = false;
- }
- }
- if( valid )
- {
- ret = snprintf( header_buf, BUFFER_SIZE-1, "%s %s\r\n", "HTTP/1.1", status_line[0] );
- len += ret;
- ret = snprintf( header_buf + len, BUFFER_SIZE-1-len,
- "Content-Length: %d\r\n", (int)file_stat.st_size );
- len += ret;
- ret = snprintf( header_buf + len, BUFFER_SIZE-1-len, "%s", "\r\n" );
- struct iovec iv[2];
- iv[ 0 ].iov_base = header_buf;
- iv[ 0 ].iov_len = strlen( header_buf );
- iv[ 1 ].iov_base = file_buf;
- iv[ 1 ].iov_len = file_stat.st_size;
- ret = writev( connfd, iv, 2 );
- }
- else
- {
- ret = snprintf( header_buf, BUFFER_SIZE-1, "%s %s\r\n", "HTTP/1.1", status_line[1] );
- len += ret;
- ret = snprintf( header_buf + len, BUFFER_SIZE-1-len, "%s", "\r\n" );
- send( connfd, header_buf, strlen( header_buf ), 0 );
- }
- close( connfd );
- delete [] file_buf;
- }
- close( sock );
- return 0;
- }
sendfile:
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <sys/sendfile.h>
- int main( int argc, char* argv[] )
- {
- if( argc <= 3 )
- {
- printf( "usage: %s ip_address port_number filename\n", basename( argv[0] ) );
- return 1;
- }
- const char* ip = argv[1];
- int port = atoi( argv[2] );
- const char* file_name = argv[3];
- int filefd = open( file_name, O_RDONLY );
- assert( filefd > 0 );
- struct stat stat_buf;
- fstat( filefd, &stat_buf );
- 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 sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 0 );
- int ret = bind( sock, ( struct sockaddr* )&address, sizeof( address ) );
- assert( ret != -1 );
- ret = listen( sock, 5 );
- assert( ret != -1 );
- struct sockaddr_in client;
- socklen_t client_addrlength = sizeof( client );
- int connfd = accept( sock, ( struct sockaddr* )&client, &client_addrlength );
- if ( connfd < 0 )
- {
- printf( "errno is: %d\n", errno );
- }
- else
- {
- //linux, not GNU. high performance send a file, 'zero copy'
- sendfile( connfd, filefd, NULL, stat_buf.st_size );
- close( connfd );
- }
- close( sock );
- return 0;
- }
splice:
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <fcntl.h>
- 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] );
- 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 sock = socket( PF_INET, SOCK_STREAM, 0 );
- assert( sock >= 0 );
- int ret = bind( sock, ( struct sockaddr* )&address, sizeof( address ) );
- assert( ret != -1 );
- ret = listen( sock, 5 );
- assert( ret != -1 );
- struct sockaddr_in client;
- socklen_t client_addrlength = sizeof( client );
- int connfd = accept( sock, ( struct sockaddr* )&client, &client_addrlength );
- if ( connfd < 0 )
- {
- printf( "errno is: %d\n", errno );
- }
- else
- {
- int pipefd[2];
- assert( ret != -1 );
- ret = pipe( pipefd ); //pipe, pipefd[0] is opened for read, pipefd[1] is opened for write.
- //splice用于在两个文件描述符之间移动数据, 也是零拷贝。使用splice时, fd_in和fd_out中必须至少有一个是管道文件描述符。
- //sendfile只适用于将数据从文件拷贝到套接字上,限定了它的使用范围。Linux在2.6.17版本引入splice系统调用,
- //用于在两个文件描述符中移动数据.
- //an ECHO implement use splice.
- //copy data from connfd(recv from client) to pipefd[1]
- ret = splice( connfd, NULL, pipefd[1], NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE );
- assert( ret != -1 );
- //copy data from pipefd[1] -->pipefd[0] --> connfd, send to client.
- ret = splice( pipefd[0], NULL, connfd, NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE );
- assert( ret != -1 );
- close( connfd );
- }
- close( sock );
- return 0;
- }
tee:
- #include <assert.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include <fcntl.h>
- int main( int argc, char* argv[] )
- {
- if ( argc != 2 )
- {
- printf( "usage: %s <file>\n", argv[0] );
- return 1;
- }
- int filefd = open( argv[1], O_CREAT | O_WRONLY | O_TRUNC, 0666 );
- assert( filefd > 0 );
- int pipefd_stdout[2];
- int ret = pipe( pipefd_stdout );
- assert( ret != -1 );
- int pipefd_file[2];
- ret = pipe( pipefd_file );
- assert( ret != -1 );
- //close( STDIN_FILENO );
- // dup2( pipefd_stdout[1], STDIN_FILENO );
- //write( pipefd_stdout[1], "abc\n", 4 );
- //copy data: stdin --> pipefd_stdout[1]
- ret = splice( STDIN_FILENO, NULL, pipefd_stdout[1], NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE );
- assert( ret != -1 );
- //tee在两个管道文件描述符之间复制数据,同是零拷贝。但它不消耗数据,数据被操作之后,仍然可以用于后续操作。
- //copy data: pipefd_stdout[0] --> pipefd_file[1]
- ret = tee( pipefd_stdout[0], pipefd_file[1], 32768, SPLICE_F_NONBLOCK );
- assert( ret != -1 );
- //copy data: pipefd_file[0] --> filefd
- ret = splice( pipefd_file[0], NULL, filefd, NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE );
- assert( ret != -1 );
- //copy data: pipefd_stdout[0] --> stdout
- ret = splice( pipefd_stdout[0], NULL, STDOUT_FILENO, NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE );
- assert( ret != -1 );
- close( filefd );
- close( pipefd_stdout[0] );
- close( pipefd_stdout[1] );
- close( pipefd_file[0] );
- close( pipefd_file[1] );
- return 0;
- }
select:
- #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>
- 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] );
- printf( "ip is %s and port is %d\n", ip, port );
- 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 );
- 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 );
- close( listenfd );
- }
- char remote_addr[INET_ADDRSTRLEN];
- printf( "connected with ip: %s and port: %d\n", inet_ntop( AF_INET, &client_address.sin_addr, remote_addr, INET_ADDRSTRLEN ), ntohs( client_address.sin_port ) );
- char buf[1024];
- fd_set read_fds;
- fd_set exception_fds;
- FD_ZERO( &read_fds );
- FD_ZERO( &exception_fds );
- // option:SO_OOBINLINE, value:1 --- put out of band data into normal data.
- int nReuseAddr = 1;
- setsockopt( connfd, SOL_SOCKET, SO_OOBINLINE, &nReuseAddr, sizeof( nReuseAddr ) );
- while( 1 )
- {
- memset( buf, '\0', sizeof( buf ) );
- FD_SET( connfd, &read_fds );
- FD_SET( connfd, &exception_fds );
- ret = select( connfd + 1, &read_fds, NULL, &exception_fds, NULL );
- printf( "select one\n" );
- if ( ret < 0 )
- {
- printf( "selection failure\n" );
- break;
- }
- if ( FD_ISSET( connfd, &read_fds ) )
- {
- ret = recv( connfd, buf, sizeof( buf )-1, 0 );
- if( ret <= 0 )
- {
- break;
- }
- printf( "get %d bytes of normal data: %s\n", ret, buf );
- }
- else if( FD_ISSET( connfd, &exception_fds ) )
- {
- ret = recv( connfd, buf, sizeof( buf )-1, MSG_OOB );
- if( ret <= 0 )
- {
- break;
- }
- printf( "get %d bytes of oob data: %s\n", ret, buf );
- }
- }
- close( connfd );
- close( listenfd );
- return 0;
- }
epoll:
- #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 BUFFER_SIZE 10
- 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, bool enable_et )
- {
- epoll_event event;
- event.data.fd = fd;
- event.events = EPOLLIN; //表示对应的文件描述符可以读(包括对端SOCKET正常关闭)
- if( enable_et )
- {
- //EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
- event.events |= EPOLLET;
- }
- epoll_ctl( epollfd, EPOLL_CTL_ADD, fd, &event ); //register to epoll
- setnonblocking( fd );
- }
- void lt( epoll_event* events, int number, int epollfd, int listenfd )
- {
- char buf[ BUFFER_SIZE ];
- 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, false );
- }
- else if ( events[i].events & EPOLLIN )
- {
- printf( "event trigger once\n" );
- memset( buf, '\0', BUFFER_SIZE );
- int ret = recv( sockfd, buf, BUFFER_SIZE-1, 0 );
- if( ret <= 0 )
- {
- close( sockfd );
- continue;
- }
- printf( "get %d bytes of content: %s\n", ret, buf );
- }
- else
- {
- printf( "something else happened \n" );
- }
- }
- }
- void et( epoll_event* events, int number, int epollfd, int listenfd )
- {
- char buf[ BUFFER_SIZE ];
- 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, true );
- }
- else if ( events[i].events & EPOLLIN )
- {
- printf( "event trigger once\n" );
- while( 1 )
- {
- memset( buf, '\0', BUFFER_SIZE );
- int ret = recv( sockfd, buf, BUFFER_SIZE-1, 0 );
- if( ret < 0 )
- {
- if( ( errno == EAGAIN ) || ( errno == EWOULDBLOCK ) )
- {
- printf( "read later\n" );
- break;
- }
- close( sockfd );
- break;
- }
- else if( ret == 0 )
- {
- close( sockfd );
- }
- else
- {
- printf( "get %d bytes of content: %s\n", ret, buf );
- }
- }
- }
- else
- {
- printf( "something else happened \n" );
- }
- }
- }
- 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 );
- epoll_event events[ MAX_EVENT_NUMBER ];
- int epollfd = epoll_create( 5 ); //tell epoll the listen number is 5
- assert( epollfd != -1 );
- addfd( epollfd, listenfd, true );
- while( 1 )
- {
- //参数events用来从内核得到事件的集合,maxevents告之内核这个events有多大,
- //这个maxevents的值不能大于创建epoll_create()时的size,参数timeout是超时时间
- //该函数返回需要处理的事件数目,如返回0表示已超时。
- int ret = epoll_wait( epollfd, events, MAX_EVENT_NUMBER, -1 );
- if ( ret < 0 )
- {
- printf( "epoll failure\n" );
- break;
- }
- lt( events, ret, epollfd, listenfd );
- //et( events, ret, epollfd, listenfd );
- }
- close( listenfd );
- return 0;
- }
oneshot:
- #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 BUFFER_SIZE 1024
- struct fds
- {
- int epollfd;
- int sockfd;
- };
- 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, bool oneshot )
- {
- epoll_event event;
- event.data.fd = fd;
- //EPOLLIN表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
- //EPOLLET将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
- event.events = EPOLLIN | EPOLLET; //
- if( oneshot )
- {
- //EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,
- //需要再次把这个socket加入到EPOLL队列里
- event.events |= EPOLLONESHOT;
- }
- //EPOLL_CTL_ADD:注册新的fd到epfd中;
- epoll_ctl( epollfd, EPOLL_CTL_ADD, fd, &event );
- setnonblocking( fd );
- }
- void reset_oneshot( int epollfd, int fd )
- {
- epoll_event event;
- event.data.fd = fd;
- event.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
- //EPOLL_CTL_MOD:修改已经注册的fd的监听事件;
- epoll_ctl( epollfd, EPOLL_CTL_MOD, fd, &event );
- }
- void* worker( void* arg )
- {
- int sockfd = ( (fds*)arg )->sockfd;
- int epollfd = ( (fds*)arg )->epollfd;
- printf( "start new thread to receive data on fd: %d\n", sockfd );
- char buf[ BUFFER_SIZE ];
- memset( buf, '\0', BUFFER_SIZE );
- while( 1 )
- {
- int ret = recv( sockfd, buf, BUFFER_SIZE-1, 0 );
- //ret=0 -- 这里表示对端的socket已正常关闭.
- if( ret == 0 )
- {
- close( sockfd );
- printf( "foreiner closed the connection\n" );
- break;
- }
- else if( ret < 0 )
- {
- //sockfd is NONBLOCK, EAGAIN -- no more data to read, so reset sockfd again
- if( errno == EAGAIN )
- {
- reset_oneshot( epollfd, sockfd );
- printf( "read later\n" );
- break;
- }
- }
- else
- {
- printf( "get content: %s\n", buf );
- sleep( 5 );
- }
- }
- printf( "end thread receiving data on fd: %d\n", sockfd );
- }
- 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 );
- epoll_event events[ MAX_EVENT_NUMBER ];
- int epollfd = epoll_create( 5 );
- assert( epollfd != -1 );
- addfd( epollfd, listenfd, false );
- while( 1 )
- {
- int ret = epoll_wait( epollfd, events, MAX_EVENT_NUMBER, -1 );
- if ( ret < 0 )
- {
- printf( "epoll failure\n" );
- break;
- }
- for ( int i = 0; i < ret; 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, true );
- }
- else if ( events[i].events & EPOLLIN )
- {
- pthread_t thread;
- fds fds_for_new_worker;
- fds_for_new_worker.epollfd = epollfd;
- fds_for_new_worker.sockfd = sockfd;
- pthread_create( &thread, NULL, worker, ( void* )&fds_for_new_worker );
- }
- else
- {
- printf( "something else happened \n" );
- }
- }
- }
- close( listenfd );
- return 0;
- }
linux socket编程示例的更多相关文章
- Linux socket编程示例(最简单的TCP和UDP两个例子)
一.socket编程 网络功能是Uinux/Linux的一个重要特点,有着悠久的历史,因此有一个非常固定的编程套路. 基于TCP的网络编程: 基于连接, 在交互过程中, 服务器和客户端要保持连接, 不 ...
- Linux Socket 编程简介
在 TCP/IP 协议中,"IP地址 + TCP或UDP端口号" 可以唯一标识网络通讯中的一个进程,"IP地址+端口号" 就称为 socket.本文以一个简单的 ...
- 多线程Java Socket编程示例
package org.merit.test.socket; import java.io.BufferedReader; import java.io.IOException; import jav ...
- Linux socket 编程中存在的五个隐患
前言: Socket API 是网络应用程序开发中实际应用的标准 API.尽管该 API 简单,但是 开发新手可能会经历一些常见的问题.本文识别一些最常见的隐患并向您显示如何避免它 ...
- Linux Socket编程
“一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...
- Linux Socket编程(不限Linux)【转】
转自:http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几 ...
- Linux Socket编程(不限Linux)
"一切皆Socket!" 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. --有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信 ...
- Socket详解-Linux Socket编程(不限Linux)
“一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...
- Windows Socket和Linux Socket编程的区别 ZZ
socket相关程序从Windows移植到Linux下需要注意的: 1)头文件 Windows下winsock.h/winsock2.h Linux下sys/socket.h 错误处理:errno.h ...
随机推荐
- 洛谷 P3320: bzoj 3991: LOJ 2182: [SDOI2015]寻宝游戏
题目传送门:LOJ #2182. 题意简述: 一棵 \(n\) 个节点的树,边有边权. 每个点可能是关键点,每次操作改变一个点是否是关键点. 求所有关键点形成的极小联通子树的边权和的两倍. 题解: 有 ...
- 【干货】Windows系统信息收集篇
市场分析:计算机取证,就是应急响应.而应急响应的市场在于黑产的攻击频率.在当今的社会里,更多的人为了钱铤而走险的比比皆是,这个市场随着比特币,大数据,物联网的来临,规模将更加的庞大与有组织性.这将导致 ...
- linux系统时间不同步解决办法(同步本地时间)
改变/etc/目录下的localtime文件,既可以改变当前的时区 1.方法是到/usr/share/zoneinfo目录下找到你要相对应的时区文件,例如上海在/usr/share/zoneinfo/ ...
- Java中获取包含变量的配置文件config.properties内容
应用场景 有些时候项目中会用到很多路径,并且很可能多个路径在同一个根目录下,那为了方便配置的修改,达到只修改根目录即可达到一改全改的效果,此时就会想到要是有变量就好了: 另外有时候路径中的文件名是不确 ...
- asp.net 文件下载显示中文名称
protected void Page_Load(object sender, EventArgs e) { string guid = Request.QueryString[& ...
- Java基础87 MySQL数据约束
1.默认值 -- 创建表student1,设置address字段有默认值 create table student1 ( id int, name ), address ) default '广东省深 ...
- java实现xml格式与javabean之间的转换XmlUtil类
XmlUtil类:不多说,直接撸代码: /** * java 转换成xml * @Title: toXml * @Description: TODO * @param obj 对象实例 * @retu ...
- shell加密
如何保护自己编写的shell程序要保护自己编写的shell脚本程序,方法有很多,最简单的方法有两种:1.加密 2.设定过期时间,下面以shc工具为例说明: 一.下载安装shc工具shc是一个加密she ...
- IntelliJ IDEA JRebel Maven Tomcat 实现热部署
一,JRebel 插件 获取与安装 直接在 IDEA 中操作获取 JRebel 插件 Paste_Image.png Paste_Image.png 安装完成,记得重启 IDEA 使刚才安装的插件生效 ...
- eaccelerator 完全手册:配置、控制、API接口
安装官方有很详细的文档 转自 http://www.enjoyphp.com/2010/eaccelerator-manual/ 配置选项 eaccelerator.shm_size指定 eAccel ...