├── 02-02_初识网络协议大家族 ├── nwchecker_client.c └── nwchecker_server.c ├── 02-06_可靠传输协议_TCP_连接建立和终止 ├── nwchecker.c ├── nwchecker.h ├── nwchecker_client.c └── nwchecker_server.c ├── 02-07_可靠传输协议_TCP_数据传输 ├── nwchecker.c ├── nwchecker.h ├── nwchecker_client.c └── nwchecker_server.c ├── 02-09_大小端之争 ├── CheckEndian.java ├── byte_order_convert.c └── endian_check.c ├── 03-10_Socket_地址结构 └── sock_addr.c ├── 03-11_最简单的TCP客户端服务器 ├── nwc_connection.c ├── nwc_connection.h ├── nwchecker.c ├── nwchecker.h ├── nwchecker_client.c └── nwchecker_server.c ├── 03-12_最简单的UDP客户端服务器 ├── nwc_connection.c ├── nwc_connection.h ├── nwc_udp_client.c ├── nwc_udp_server.c ├── nwchecker.c ├── nwchecker.h ├── nwchecker_client.c └── nwchecker_server.c ├── 03-13_UNIX域套接字编程 ├── nwc_connection.c ├── nwc_connection.h ├── nwc_udp_client.c ├── nwc_udp_server.c ├── nwchecker.c ├── nwchecker.h ├── nwchecker_client.c ├── nwchecker_server.c ├── tcp_unix_stream_test.txt ├── unix_dgram_client.c ├── unix_dgram_server.c ├── unix_stream_client.c └── unix_stream_server.c ├── 03-14_掌控你的Socket套接口 └── sock_option.c ├── 03-15_通过域名进行编程 └── domain_name_resolve.c ├── 03-16_获取网卡IP地址 └── showif.c ├── 03-17_认识select和poll ├── poll_demo.c └── select_demo.c ├── 03-18_非阻塞Socket编程 ├── nwc_connection.c ├── nwc_connection.h ├── nwc_udp_client.c ├── nwc_udp_server.c ├── nwchecker.c ├── nwchecker.h ├── nwchecker_client.c ├── nwchecker_server.c ├── tcp_unix_stream_test.txt ├── unix_dgram_client.c ├── unix_dgram_server.c ├── unix_stream_client.c └── unix_stream_server.c ├── 03-19_理解linux_epoll的工作原理 ├── nwc_connection.c ├── nwc_connection.h ├── nwc_udp_client.c ├── nwc_udp_server.c ├── nwchecker.c ├── nwchecker.h ├── nwchecker_client.c ├── nwchecker_server.c ├── tcp_unix_stream_test.txt ├── unix_dgram_client.c ├── unix_dgram_server.c ├── unix_stream_client.c └── unix_stream_server.c ├── 03-21_理解Windows_WSASelect的工作原理 └── wsaselectdemo │ ├── .vs │ └── wsaselectdemo │ │ └── v14 │ │ └── .suo │ ├── wsaselectdemo.VC.db │ ├── wsaselectdemo.sln │ ├── wsaselectdemo_client │ ├── nwchecker_client.c │ ├── wsaselectdemo_client.vcxproj │ ├── wsaselectdemo_client.vcxproj.filters │ └── wsaselectdemo_client.vcxproj.user │ └── wsaselectdemo_server │ ├── nwchecker_server.c │ ├── wsaselectdemo_server.vcxproj │ ├── wsaselectdemo_server.vcxproj.filters │ └── wsaselectdemo_server.vcxproj.user ├── 04-23_高级IO函数 ├── nwc_connection.c ├── nwc_connection.h ├── nwc_udp_client.c ├── nwc_udp_server.c ├── nwchecker.c ├── nwchecker.h ├── nwchecker_client.c ├── nwchecker_server.c ├── nwchecker_server_multiprocess.c ├── tcp_unix_stream_test.txt ├── unix_dgram_client.c ├── unix_dgram_server.c ├── unix_stream_client.c └── unix_stream_server.c ├── 04-24_UNIX异步IO机制 ├── nwc_connection.c ├── nwc_connection.h ├── nwc_udp_client.c ├── nwc_udp_server.c ├── nwchecker.c ├── nwchecker.h ├── nwchecker_client.c ├── nwchecker_server.c ├── nwchecker_server_multiprocess.c ├── sigio_udp_server.c ├── tcp_unix_stream_test.txt ├── unix_dgram_client.c ├── unix_dgram_server.c ├── unix_stream_client.c └── unix_stream_server.c ├── 04-25_Windows_IOCP机制 └── iocp_server │ ├── iocp_server.sln │ ├── iocp_server.vcxproj │ ├── iocp_server.vcxproj.filters │ ├── iocp_server.vcxproj.user │ ├── nwc_connection.c │ ├── nwc_connection.h │ ├── nwchecker_server.c │ ├── nwcs_iocp.cpp │ └── nwcs_iocp.h ├── 04-26_基于UDP组播的编程 ├── mcast.c ├── mcast.h ├── mcast_client.c └── mcast_server.c ├── 04-30_nwchecker_refactor ├── Makefile ├── list.h ├── nwc.c ├── nwc.h ├── nwc_client.c ├── nwc_configuration.c ├── nwc_configuration.h ├── nwc_connection.c ├── nwc_connection.h ├── nwc_epoll_looper.c ├── nwc_epoll_looper.h ├── nwc_io_handler.h ├── nwc_looper.c ├── nwc_looper.h ├── nwc_main.c ├── nwc_qos_protocol.c ├── nwc_qos_protocol.h ├── nwc_server.c ├── nwc_sock.c ├── nwc_sock.h ├── nwc_tcp_handler.c ├── nwc_tcp_handler.h ├── nwc_types.h ├── nwc_udp_handler.c └── nwc_udp_handler.h ├── README.md └── java_netprogramming ├── .idea ├── dictionaries │ └── Administrator.xml ├── encodings.xml ├── misc.xml ├── modules.xml ├── uiDesigner.xml └── workspace.xml ├── java_netprogramming.iml └── src └── com └── haska ├── asynchronous ├── AsyncClient.java ├── AsyncClientFuture.java ├── AsyncServer.java └── AsyncServerCompletionHandler.java ├── buffer └── ByteBufferDemo.java ├── multithreadserver ├── TCPClientMultiThread.java ├── TCPServerPerThread.java └── TCPServerThreadPool.java ├── netaddr └── NetAddrDemo.java ├── network ├── CustomEventObject.java ├── IOAdapter.java ├── IOHandler.java ├── Listener.java └── impl │ ├── AbstractAdapter.java │ ├── Acceptor.java │ ├── IOThread.java │ ├── Poller.java │ ├── SocketHandler.java │ ├── TcpHandler.java │ └── ThreadPool.java ├── nonblock ├── NonblockTCPClient.java └── NonblockTCPServer.java ├── sockoption └── SockOptions.java ├── tcp ├── TCPClient.java └── TCPServer.java ├── tcpio ├── TCPClientIO.java └── TCPServerIO.java ├── udp ├── UDPClient.java └── UDPServer.java └── udpio ├── Message.java ├── UDPClientIO.java └── UDPServerIO.java /02-02_初识网络协议大家族/nwchecker_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include // inet_addr() 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | int rc = 0; 14 | int sock_fd = -1; 15 | struct sockaddr_in serveraddr; 16 | 17 | const char *ping = "ping"; 18 | size_t ping_len = strlen(ping); 19 | 20 | // Used to receive the "pong" message from the server. 21 | char recv_buffer[8] = {0}; 22 | 23 | 24 | if (argc < 3){ 25 | printf("Please input: nwchecker_client ip port\n"); 26 | return -1; 27 | } 28 | 29 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); 30 | if (sock_fd == -1){ 31 | printf("Create socket failed! errno(%d)\n", errno); 32 | return -1; 33 | } 34 | 35 | memset(&serveraddr, 0, sizeof(serveraddr)); 36 | 37 | serveraddr.sin_family = AF_INET; 38 | serveraddr.sin_port = htons(atoi(argv[2])); 39 | serveraddr.sin_addr.s_addr = inet_addr(argv[1]); 40 | 41 | rc = connect(sock_fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 42 | if (rc == -1){ 43 | printf("Connect server failed! errno(%d)\n", errno); 44 | return -1; 45 | } 46 | 47 | while(1){ 48 | rc = send(sock_fd, ping, ping_len, 0); 49 | if (rc == -1){ 50 | printf("Send ping request failed! errno(%d)\n", errno); 51 | break; 52 | } 53 | 54 | printf("%ld Send %s to server!\n", time(NULL), ping); 55 | 56 | rc = recv(sock_fd, recv_buffer, 7, 0); 57 | if (rc == 0){ 58 | printf("The connection is closed by peer!"); 59 | break; 60 | } 61 | 62 | if (rc == -1){ 63 | printf("Receive message failed!errno(%d)\n", errno); 64 | break; 65 | } 66 | 67 | printf("%ld Recv %s from the server\n", time(NULL), recv_buffer); 68 | 69 | // Sleep 3 seconds 70 | sleep(3); 71 | } 72 | 73 | close(sock_fd); 74 | 75 | return 0; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /02-02_初识网络协议大家族/nwchecker_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include // inet_addr() 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | int rc = 0; 14 | int sock_fd = -1; 15 | struct sockaddr_in server_addr; 16 | struct sockaddr_in client_addr; 17 | socklen_t client_addr_len; 18 | 19 | const char *pong = "pong"; 20 | size_t pong_len = strlen(pong); 21 | 22 | // Used to receive the "ping" message from the server. 23 | char recv_buffer[8] = {0}; 24 | int client_sock_fd = -1; 25 | 26 | 27 | if (argc < 2){ 28 | printf("Please input: nwchecker_server port\n"); 29 | return -1; 30 | } 31 | 32 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); 33 | if (sock_fd == -1){ 34 | printf("Create socket failed! errno(%d)\n", errno); 35 | return -1; 36 | } 37 | 38 | memset(&client_addr, 0, sizeof(client_addr)); 39 | memset(&server_addr, 0, sizeof(server_addr)); 40 | 41 | server_addr.sin_family = AF_INET; 42 | server_addr.sin_port = htons(atoi(argv[1])); 43 | server_addr.sin_addr.s_addr = INADDR_ANY; 44 | 45 | rc = bind(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)); 46 | if (rc == -1){ 47 | printf("Bind server failed! errno(%d)\n", errno); 48 | return -1; 49 | } 50 | 51 | rc = listen(sock_fd, 3); 52 | if (rc == -1){ 53 | printf("Server listen failed! errno(%d)\n", errno); 54 | return -1; 55 | } 56 | 57 | client_addr_len = sizeof(client_addr); 58 | 59 | client_sock_fd = accept(sock_fd, (struct sockaddr*)&client_addr, (socklen_t*)&client_addr_len); 60 | if (client_sock_fd == -1){ 61 | printf("Accept connection from client failed! sockf_fd(%d) errno(%d)\n", sock_fd, errno); 62 | return -1; 63 | } 64 | 65 | while(1){ 66 | rc = recv(client_sock_fd, recv_buffer, 7, 0); 67 | if (rc == 0){ 68 | printf("The connection is closed by peer!"); 69 | break; 70 | } 71 | 72 | if (rc == -1){ 73 | printf("Receive message failed!errno(%d)\n", errno); 74 | break; 75 | } 76 | 77 | printf("%ld Recv %s from the client\n", time(NULL), recv_buffer); 78 | 79 | rc = send(client_sock_fd, pong, pong_len, 0); 80 | if (rc == -1){ 81 | printf("Send ping reponse failed! errno(%d)\n", errno); 82 | break; 83 | } 84 | 85 | printf("%ld Send %s to client !\n", time(NULL), pong); 86 | 87 | } 88 | 89 | close(sock_fd); 90 | close(client_sock_fd); 91 | 92 | return 0; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /02-06_可靠传输协议_TCP_连接建立和终止/nwchecker.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "nwchecker.h" 7 | 8 | void usage() 9 | { 10 | fprintf(stderr, "Usage: nwchecker [option]\n"); 11 | fprintf(stderr, " --help -h help information\n"); 12 | fprintf(stderr, " --client -c The client mode.\n"); 13 | fprintf(stderr, " --server -s The server mode.\n"); 14 | fprintf(stderr, " --port -p The server port.\n"); 15 | fprintf(stderr, " --address -a The server address.\n"); 16 | fprintf(stderr, " --count -u The number of the test.\n"); 17 | fprintf(stderr, " --no-close -n Don't close the socket.\n"); 18 | exit(0); 19 | } 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | int c; 24 | int mode=0; 25 | 26 | struct nwc_args na; 27 | 28 | memset(&na, 0, sizeof(na)); 29 | 30 | if (argc < 2){ 31 | usage(); 32 | return 0; 33 | } 34 | 35 | while (1) { 36 | int option_index = 0; 37 | static struct option long_options[] = { 38 | {"help", no_argument, 0, 'h'}, 39 | {"client", no_argument, 0, 'c'}, 40 | {"server", no_argument, 0, 's'}, 41 | {"no-close", no_argument, 0, 'n'}, 42 | {"port", required_argument, 0, 'p'}, 43 | {"address", required_argument, 0, 'a'}, 44 | {"count", required_argument, 0, 'u'}, 45 | {0, 0, 0, 0 } 46 | }; 47 | 48 | c = getopt_long(argc, argv, "hcsnp:a:u:", long_options, &option_index); 49 | if (c == -1) 50 | break; 51 | 52 | switch (c) { 53 | case 'h': 54 | usage(); 55 | break; 56 | case 'c': 57 | mode = 1; 58 | break; 59 | case 's': 60 | mode =2; 61 | break; 62 | case 'p': 63 | na.port = atoi(optarg); 64 | break; 65 | case 'a': 66 | na.ip = optarg; 67 | break; 68 | case 'u': 69 | na.count = atoi(optarg); 70 | break; 71 | case 'n': 72 | na.no_close = 1; 73 | break; 74 | default: 75 | usage(); 76 | } 77 | } 78 | 79 | if (mode == 1){ 80 | // nwc client 81 | nwc_client(&na); 82 | }else if (mode == 2){ 83 | // nwc server 84 | nwc_server(&na); 85 | } 86 | 87 | return 0; 88 | } 89 | 90 | -------------------------------------------------------------------------------- /02-06_可靠传输协议_TCP_连接建立和终止/nwchecker.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWCHECER_H_ 2 | #define _NWCHECER_H_ 3 | 4 | 5 | struct nwc_args 6 | { 7 | const char *ip; 8 | unsigned short port; 9 | int count; 10 | int no_close; 11 | }; 12 | 13 | int nwc_client(struct nwc_args *na); 14 | int nwc_server(struct nwc_args *na); 15 | 16 | #endif//_NWCHECER_H_ 17 | 18 | -------------------------------------------------------------------------------- /02-06_可靠传输协议_TCP_连接建立和终止/nwchecker_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include // inet_addr() 10 | 11 | #include "nwchecker.h" 12 | 13 | int nwc_client(struct nwc_args *na) 14 | { 15 | int rc = 0; 16 | int sock_fd = -1; 17 | struct sockaddr_in serveraddr; 18 | 19 | const char *ping = "ping"; 20 | size_t ping_len = strlen(ping); 21 | 22 | // Used to receive the "pong" message from the server. 23 | char recv_buffer[8] = {0}; 24 | 25 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); 26 | if (sock_fd == -1){ 27 | printf("Create socket failed! errno(%d)\n", errno); 28 | return -1; 29 | } 30 | 31 | memset(&serveraddr, 0, sizeof(serveraddr)); 32 | 33 | serveraddr.sin_family = AF_INET; 34 | serveraddr.sin_port = htons(na->port); 35 | serveraddr.sin_addr.s_addr = inet_addr(na->ip); 36 | 37 | rc = connect(sock_fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 38 | if (rc == -1){ 39 | printf("Connect server failed! errno(%d)\n", errno); 40 | return -1; 41 | } 42 | 43 | int infinit = na->count <= 0 ? 1:0; 44 | int loop_count = na->count; 45 | 46 | while(1){ 47 | rc = send(sock_fd, ping, ping_len, 0); 48 | if (rc == -1){ 49 | printf("Send ping request failed! errno(%d)\n", errno); 50 | break; 51 | } 52 | 53 | printf("%ld Send %s to server!\n", time(NULL), ping); 54 | 55 | rc = recv(sock_fd, recv_buffer, 7, 0); 56 | if (rc == 0){ 57 | printf("The connection is closed by peer!\n"); 58 | break; 59 | } 60 | 61 | if (rc == -1){ 62 | printf("Receive message failed!errno(%d)\n", errno); 63 | break; 64 | } 65 | 66 | printf("%ld Recv %s from the server\n", time(NULL), recv_buffer); 67 | 68 | if (!infinit){ 69 | loop_count--; 70 | if (loop_count == 0){ 71 | break;// exit loop 72 | } 73 | } 74 | 75 | // Sleep 3 seconds 76 | sleep(3); 77 | } 78 | 79 | if (!na->no_close){ 80 | close(sock_fd); 81 | } 82 | 83 | return 0; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /02-06_可靠传输协议_TCP_连接建立和终止/nwchecker_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include // inet_addr() 10 | 11 | #include "nwchecker.h" 12 | 13 | int nwc_server(struct nwc_args *na) 14 | { 15 | int rc = 0; 16 | int sock_fd = -1; 17 | struct sockaddr_in server_addr; 18 | struct sockaddr_in client_addr; 19 | socklen_t client_addr_len; 20 | 21 | const char *pong = "pong"; 22 | size_t pong_len = strlen(pong); 23 | 24 | // Used to receive the "ping" message from the server. 25 | char recv_buffer[8] = {0}; 26 | int client_sock_fd = -1; 27 | 28 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); 29 | if (sock_fd == -1){ 30 | printf("Create socket failed! errno(%d)\n", errno); 31 | return -1; 32 | } 33 | 34 | memset(&client_addr, 0, sizeof(client_addr)); 35 | memset(&server_addr, 0, sizeof(server_addr)); 36 | 37 | server_addr.sin_family = AF_INET; 38 | server_addr.sin_port = htons(na->port); 39 | server_addr.sin_addr.s_addr = INADDR_ANY; 40 | 41 | rc = bind(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)); 42 | if (rc == -1){ 43 | printf("Bind server failed! errno(%d)\n", errno); 44 | return -1; 45 | } 46 | 47 | rc = listen(sock_fd, 3); 48 | if (rc == -1){ 49 | printf("Server listen failed! errno(%d)\n", errno); 50 | return -1; 51 | } 52 | 53 | client_addr_len = sizeof(client_addr); 54 | 55 | client_sock_fd = accept(sock_fd, (struct sockaddr*)&client_addr, (socklen_t*)&client_addr_len); 56 | if (client_sock_fd == -1){ 57 | printf("Accept connection from client failed! errno(%d)\n", errno); 58 | return -1; 59 | } 60 | 61 | while(1){ 62 | rc = recv(client_sock_fd, recv_buffer, 7, 0); 63 | if (rc == 0){ 64 | printf("The connection is closed by peer!\n"); 65 | break; 66 | } 67 | 68 | if (rc == -1){ 69 | printf("Receive message failed!errno(%d)\n", errno); 70 | break; 71 | } 72 | 73 | printf("%ld Recv %s from the client\n", time(NULL), recv_buffer); 74 | 75 | rc = send(client_sock_fd, pong, pong_len, 0); 76 | if (rc == -1){ 77 | printf("Send ping reponse failed! errno(%d)\n", errno); 78 | break; 79 | } 80 | 81 | printf("%ld Send %s to client !\n", time(NULL), pong); 82 | 83 | } 84 | 85 | if (!na->no_close){ 86 | close(sock_fd); 87 | close(client_sock_fd); 88 | } 89 | 90 | return 0; 91 | } 92 | 93 | -------------------------------------------------------------------------------- /02-07_可靠传输协议_TCP_数据传输/nwchecker.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWCHECER_H_ 2 | #define _NWCHECER_H_ 3 | 4 | 5 | struct nwc_args 6 | { 7 | const char *ip; 8 | unsigned short port; 9 | int count; 10 | int no_close; 11 | int interval; // The unit is ms 12 | int sent_pkgs; // The sent packages of every slot. 13 | int message_size; // The send message size. 14 | int echo_mode; // 0:immediate, 1: random time, 2: no response, 3: server not recv 15 | }; 16 | 17 | int nwc_client(struct nwc_args *na); 18 | int nwc_server(struct nwc_args *na); 19 | 20 | char * alloc_buffer(int alloc_size); 21 | void free_buffer(char *buff); 22 | 23 | 24 | #endif//_NWCHECER_H_ 25 | 26 | -------------------------------------------------------------------------------- /02-07_可靠传输协议_TCP_数据传输/nwchecker_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include // inet_addr() 10 | 11 | #include "nwchecker.h" 12 | 13 | int nwc_client(struct nwc_args *na) 14 | { 15 | int rc = 0; 16 | int sock_fd = -1; 17 | struct sockaddr_in serveraddr; 18 | 19 | char *send_msg = NULL; 20 | size_t send_msg_len = 0; 21 | 22 | // Used to receive the "pong" message from the server. 23 | char recv_buffer[8] = {0}; 24 | 25 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); 26 | if (sock_fd == -1){ 27 | printf("Create socket failed! errno(%d)\n", errno); 28 | return -1; 29 | } 30 | 31 | memset(&serveraddr, 0, sizeof(serveraddr)); 32 | 33 | serveraddr.sin_family = AF_INET; 34 | serveraddr.sin_port = htons(na->port); 35 | serveraddr.sin_addr.s_addr = inet_addr(na->ip); 36 | 37 | rc = connect(sock_fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 38 | if (rc == -1){ 39 | printf("Connect server failed! errno(%d)\n", errno); 40 | return -1; 41 | } 42 | 43 | send_msg_len = na->message_size <= 0?5:na->message_size; 44 | send_msg = alloc_buffer(send_msg_len); 45 | 46 | useconds_t sleep_time = na->interval <= 0 ? 3000 : na->interval; 47 | int slot_send_count = na->sent_pkgs <= 0? 1: na->sent_pkgs; 48 | int cur_slot_sent = slot_send_count; 49 | int infinit = na->count <= 0 ? 1:0; 50 | int loop_count = na->count * slot_send_count; 51 | int echo_mode = na->echo_mode; 52 | 53 | printf("nwc client. slot_send_count(%d) infinit(%d) loop_count(%d) echo_mode(%d) sleep_time(%d)\n", 54 | slot_send_count, 55 | infinit, 56 | loop_count, 57 | echo_mode, 58 | sleep_time); 59 | 60 | while(1){ 61 | rc = send(sock_fd, send_msg, send_msg_len, 0); 62 | if (rc == -1){ 63 | printf("Send ping request failed! errno(%d)\n", errno); 64 | break; 65 | } 66 | 67 | if (send_msg_len <= 5){ 68 | printf("%ld Send %s to server!\n", time(NULL), send_msg); 69 | }else{ 70 | printf("%ld Send %ld message to server!\n", time(NULL), send_msg_len); 71 | } 72 | 73 | if (echo_mode != 2){ 74 | rc = recv(sock_fd, recv_buffer, 7, 0); 75 | if (rc == 0){ 76 | printf("The connection is closed by peer!\n"); 77 | break; 78 | } 79 | 80 | if (rc == -1){ 81 | printf("Receive message failed!errno(%d)\n", errno); 82 | break; 83 | } 84 | 85 | printf("%ld Recv %s from the server\n", time(NULL), recv_buffer); 86 | } 87 | 88 | if (!infinit){ 89 | loop_count--; 90 | if (loop_count == 0){ 91 | break;// exit loop 92 | } 93 | } 94 | 95 | // Sleep 3 seconds 96 | //sleep(3); 97 | cur_slot_sent--; 98 | if (cur_slot_sent == 0){ 99 | usleep(sleep_time * 1000); 100 | cur_slot_sent = slot_send_count; 101 | } 102 | } 103 | 104 | if (!na->no_close){ 105 | close(sock_fd); 106 | } 107 | 108 | if (send_msg){ 109 | free_buffer(send_msg); 110 | send_msg = NULL; 111 | } 112 | 113 | return 0; 114 | } 115 | 116 | -------------------------------------------------------------------------------- /02-07_可靠传输协议_TCP_数据传输/nwchecker_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include // inet_addr() 10 | 11 | #include "nwchecker.h" 12 | 13 | #define RECV_BUFF_LEN 4*1024*1024 14 | 15 | int nwc_server(struct nwc_args *na) 16 | { 17 | int rc = 0; 18 | int sock_fd = -1; 19 | struct sockaddr_in server_addr; 20 | struct sockaddr_in client_addr; 21 | socklen_t client_addr_len; 22 | 23 | const char *pong = "pong"; 24 | size_t pong_len = strlen(pong); 25 | 26 | // Used to receive the "ping" message from the server. 27 | char *recv_buffer = NULL; 28 | size_t recv_buffer_len = RECV_BUFF_LEN; 29 | int client_sock_fd = -1; 30 | 31 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); 32 | if (sock_fd == -1){ 33 | printf("Create socket failed! errno(%d)\n", errno); 34 | return -1; 35 | } 36 | 37 | memset(&client_addr, 0, sizeof(client_addr)); 38 | memset(&server_addr, 0, sizeof(server_addr)); 39 | 40 | server_addr.sin_family = AF_INET; 41 | server_addr.sin_port = htons(na->port); 42 | server_addr.sin_addr.s_addr = INADDR_ANY; 43 | 44 | rc = bind(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)); 45 | if (rc == -1){ 46 | printf("Bind server failed! errno(%d)\n", errno); 47 | return -1; 48 | } 49 | 50 | rc = listen(sock_fd, 3); 51 | if (rc == -1){ 52 | printf("Server listen failed! errno(%d)\n", errno); 53 | return -1; 54 | } 55 | 56 | int echo_mode = na->echo_mode; 57 | useconds_t sleep_time = na->interval < 0 ? 0:na->interval; 58 | 59 | client_addr_len = sizeof(client_addr); 60 | client_sock_fd = accept(sock_fd, (struct sockaddr*)&client_addr, (socklen_t*)&client_addr_len); 61 | if (client_sock_fd == -1){ 62 | printf("Accept connection from client failed! errno(%d)\n", errno); 63 | return -1; 64 | } 65 | 66 | recv_buffer = alloc_buffer(RECV_BUFF_LEN); 67 | 68 | while(1){ 69 | if (echo_mode != 3){ 70 | rc = recv(client_sock_fd, recv_buffer, RECV_BUFF_LEN, 0); 71 | if (rc == 0){ 72 | printf("The connection is closed by peer!\n"); 73 | break; 74 | } 75 | 76 | if (rc == -1){ 77 | printf("Receive message failed!errno(%d)\n", errno); 78 | break; 79 | } 80 | 81 | printf("%ld Recv %s from the client\n", time(NULL), recv_buffer); 82 | } 83 | 84 | if ( sleep_time > 0){ 85 | usleep(sleep_time * 1000); 86 | } 87 | 88 | if ( echo_mode != 2){ 89 | rc = send(client_sock_fd, pong, pong_len, 0); 90 | if (rc == -1){ 91 | printf("Send ping reponse failed! errno(%d)\n", errno); 92 | break; 93 | } 94 | printf("%ld Send %s to client !\n", time(NULL), pong); 95 | } 96 | } 97 | 98 | if (!na->no_close){ 99 | close(sock_fd); 100 | close(client_sock_fd); 101 | } 102 | 103 | if (recv_buffer){ 104 | free_buffer(recv_buffer); 105 | recv_buffer = NULL; 106 | } 107 | return 0; 108 | } 109 | 110 | -------------------------------------------------------------------------------- /02-09_大小端之争/CheckEndian.java: -------------------------------------------------------------------------------- 1 | import java.nio.ByteBuffer; 2 | 3 | public class CheckEndian 4 | { 5 | public static void checkEndian() 6 | { 7 | int x = 0xAABBCCDD; 8 | 9 | ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); 10 | buffer.putInt(x); 11 | byte[] lbytes = buffer.array(); 12 | for (byte b : lbytes){ 13 | System.out.printf("%X\n", b); 14 | } 15 | } 16 | public static void main(String[] args) 17 | { 18 | checkEndian(); 19 | } 20 | } -------------------------------------------------------------------------------- /02-09_大小端之争/byte_order_convert.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void show_bytes(int n) 5 | { 6 | unsigned char *ptr_n = (unsigned char*)&n; 7 | 8 | for (int i = 0; i < 4; ++i){ 9 | printf("%X\n", *ptr_n++); 10 | } 11 | } 12 | 13 | void byte_order_convert() 14 | { 15 | int x = 0xAABBCCDD; 16 | 17 | printf("Before byte order convert\n"); 18 | show_bytes(x); 19 | 20 | int ax = htonl(x); 21 | printf("After byte order convert\n"); 22 | show_bytes(ax); 23 | } 24 | 25 | int main(int argc, char *argv[]) 26 | { 27 | byte_order_convert(); 28 | return 0; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /02-09_大小端之争/endian_check.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void check_endian() 4 | { 5 | int n = 0xAABBCCDD; 6 | 7 | unsigned char *ptr_n = (unsigned char*)&n; 8 | 9 | for (int i=0; i < 4; ++i){ 10 | printf("%X\n", *ptr_n++); 11 | } 12 | } 13 | 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | check_endian(); 18 | 19 | return 0; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /03-10_Socket_地址结构/sock_addr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void test_sock_addr_length() 8 | { 9 | printf("The length of struct sockaddr_in: %d\n", sizeof(struct sockaddr_in)); 10 | printf("The length of struct sockaddr_in6: %d\n", sizeof(struct sockaddr_in6)); 11 | printf("The length of struct sockaddr_un: %d\n", sizeof(struct sockaddr_un)); 12 | printf("The length of struct sockaddr: %d\n", sizeof(struct sockaddr)); 13 | printf("The length of struct sockaddr_storage: %d\n", sizeof(struct sockaddr_storage)); 14 | } 15 | 16 | void init_sock_addr(int af, struct sockaddr_storage *ss, unsigned short port, const char *addr) 17 | { 18 | ss->ss_family = af; 19 | if (af == AF_INET){ 20 | struct sockaddr_in *si = (struct sockaddr_in*)ss; 21 | si->sin_port = htons(port); 22 | si->sin_addr.s_addr = inet_addr(addr); 23 | }else if (af == AF_INET6){ 24 | struct sockaddr_in6 *si6 = (struct sockaddr_in6*)ss; 25 | si6->sin6_port = htons(port); 26 | inet_pton(af, addr, &si6->sin6_addr); 27 | }else{ 28 | printf("No support af(%d)\n", af); 29 | } 30 | } 31 | 32 | void test_sock_addr() 33 | { 34 | // Test ipv4 address 35 | struct sockaddr_in ipv4_addr; 36 | 37 | ipv4_addr.sin_family = AF_INET; 38 | // Use htons convert port 39 | ipv4_addr.sin_port = htons(80); 40 | // use inet_addr 41 | ipv4_addr.sin_addr.s_addr = inet_addr("192.168.0.1"); 42 | // use inet_aton 43 | inet_aton("192.168.0.1", &ipv4_addr.sin_addr); 44 | 45 | char *ip = inet_ntoa(ipv4_addr.sin_addr); 46 | 47 | printf("IPv4 Address after convert %s\n", ip); 48 | 49 | // Test ipv6 address 50 | struct sockaddr_in6 ipv6_addr; 51 | ipv6_addr.sin6_family = AF_INET6; 52 | ipv6_addr.sin6_port = htons(80); 53 | inet_pton(AF_INET6, "2001:0db8::0001", &ipv6_addr.sin6_addr); 54 | 55 | char v6addr[64] = {0}; 56 | inet_ntop(AF_INET6, &ipv6_addr.sin6_addr, v6addr, 63); 57 | 58 | printf("IPv6 Address after convert %s\n", v6addr); 59 | 60 | // General sockaddr 61 | struct sockaddr_storage ss; 62 | 63 | init_sock_addr(AF_INET, &ss, 80, "192.168.0.1"); 64 | init_sock_addr(AF_INET6, &ss, 80, "2001:168::1"); 65 | } 66 | 67 | int main(int argc, char *argv[]) 68 | { 69 | test_sock_addr_length(); 70 | test_sock_addr(); 71 | 72 | return 0; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /03-11_最简单的TCP客户端服务器/nwc_connection.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "nwc_connection.h" 4 | 5 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd) 6 | { 7 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 8 | 9 | nwc->next = nwc; 10 | nwc->prev = nwc; 11 | nwc->pid = pid; 12 | nwc->fd = fd; 13 | 14 | return nwc; 15 | } 16 | 17 | void free_nwc_conn(struct nwc_connection *nwc) 18 | { 19 | if (nwc){ 20 | free(nwc); 21 | nwc = NULL; 22 | } 23 | } 24 | 25 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc) 26 | { 27 | struct nwc_connection *prev = hdr->prev; 28 | struct nwc_connection *next = hdr; 29 | nwc->prev = prev; 30 | nwc->next = next; 31 | prev->next = nwc; 32 | next->prev = nwc; 33 | } 34 | 35 | void remove_nwc(struct nwc_connection *nwc) 36 | { 37 | struct nwc_connection *prev = nwc->prev; 38 | struct nwc_connection *next = nwc->next; 39 | 40 | prev->next = next; 41 | next->prev = prev; 42 | } 43 | void destroy_all_nwc(struct nwc_connection *hdr) 44 | { 45 | struct nwc_connection *nwc = hdr->next; 46 | for (; nwc != hdr;){ 47 | struct nwc_connection *next = nwc->next; 48 | free_nwc_conn(nwc); 49 | nwc = next; 50 | } 51 | } 52 | 53 | 54 | -------------------------------------------------------------------------------- /03-11_最简单的TCP客户端服务器/nwc_connection.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_CONNECTION_H_ 2 | #define _NWC_CONNECTION_H_ 3 | 4 | #include 5 | 6 | struct nwc_connection 7 | { 8 | struct nwc_connection *next; 9 | struct nwc_connection *prev; 10 | 11 | pid_t pid; 12 | int fd; 13 | int echo_mode; 14 | int sleep_time; 15 | }; 16 | 17 | #define INIT_NWC(nwc)\ 18 | do { \ 19 | (nwc)->next = (nwc);\ 20 | (nwc)->prev = (nwc);\ 21 | (nwc)->pid = 0;\ 22 | (nwc)->fd = -1;\ 23 | }while(0); 24 | 25 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd); 26 | void free_nwc_conn(struct nwc_connection *nwc); 27 | 28 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc); 29 | void remove_nwc(struct nwc_connection *nwc); 30 | void destroy_all_nwc(struct nwc_connection *hdr); 31 | 32 | 33 | #endif//_NWC_CONNECTION_H_ 34 | 35 | -------------------------------------------------------------------------------- /03-11_最简单的TCP客户端服务器/nwchecker.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWCHECER_H_ 2 | #define _NWCHECER_H_ 3 | 4 | 5 | struct nwc_args 6 | { 7 | const char *ip; 8 | unsigned short port; 9 | int count; 10 | int no_close; 11 | int interval; // The unit is ms 12 | int sent_pkgs; // The sent packages of every slot. 13 | int message_size; // The send message size. 14 | int echo_mode; // 0:immediate, 1: random time, 2: no response, 3: server not recv 15 | }; 16 | 17 | int nwc_client(struct nwc_args *na); 18 | int nwc_server(struct nwc_args *na); 19 | 20 | char * alloc_buffer(int alloc_size); 21 | void free_buffer(char *buff); 22 | 23 | 24 | #endif//_NWCHECER_H_ 25 | 26 | -------------------------------------------------------------------------------- /03-11_最简单的TCP客户端服务器/nwchecker_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include // inet_addr() 10 | 11 | #include "nwchecker.h" 12 | 13 | int nwc_client(struct nwc_args *na) 14 | { 15 | int rc = 0; 16 | int sock_fd = -1; 17 | struct sockaddr_in serveraddr; 18 | 19 | char *send_msg = NULL; 20 | size_t send_msg_len = 0; 21 | 22 | // Used to receive the "pong" message from the server. 23 | char recv_buffer[8] = {0}; 24 | 25 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); 26 | if (sock_fd == -1){ 27 | printf("Create socket failed! errno(%d)\n", errno); 28 | return -1; 29 | } 30 | 31 | memset(&serveraddr, 0, sizeof(serveraddr)); 32 | 33 | serveraddr.sin_family = AF_INET; 34 | serveraddr.sin_port = htons(na->port); 35 | serveraddr.sin_addr.s_addr = inet_addr(na->ip); 36 | 37 | rc = connect(sock_fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 38 | if (rc == -1){ 39 | printf("Connect server failed! errno(%d)\n", errno); 40 | return -1; 41 | } 42 | 43 | send_msg_len = na->message_size <= 0?5:na->message_size; 44 | send_msg = alloc_buffer(send_msg_len); 45 | 46 | useconds_t sleep_time = na->interval <= 0 ? 3000 : na->interval; 47 | int slot_send_count = na->sent_pkgs <= 0? 1: na->sent_pkgs; 48 | int cur_slot_sent = slot_send_count; 49 | int infinit = na->count <= 0 ? 1:0; 50 | int loop_count = na->count * slot_send_count; 51 | int echo_mode = na->echo_mode; 52 | 53 | printf("nwc client. slot_send_count(%d) infinit(%d) loop_count(%d) echo_mode(%d) sleep_time(%d)\n", 54 | slot_send_count, 55 | infinit, 56 | loop_count, 57 | echo_mode, 58 | sleep_time); 59 | 60 | while(1){ 61 | rc = send(sock_fd, send_msg, send_msg_len, 0); 62 | if (rc == -1){ 63 | printf("Send ping request failed! errno(%d)\n", errno); 64 | break; 65 | } 66 | 67 | if (send_msg_len <= 5){ 68 | printf("%ld Send %s to server!\n", time(NULL), send_msg); 69 | }else{ 70 | printf("%ld Send %ld message to server!\n", time(NULL), send_msg_len); 71 | } 72 | 73 | if (echo_mode != 2){ 74 | rc = recv(sock_fd, recv_buffer, 7, 0); 75 | if (rc == 0){ 76 | printf("The connection is closed by peer!\n"); 77 | break; 78 | } 79 | 80 | if (rc == -1){ 81 | printf("Receive message failed!errno(%d)\n", errno); 82 | break; 83 | } 84 | 85 | printf("%ld Recv %s from the server\n", time(NULL), recv_buffer); 86 | } 87 | 88 | if (!infinit){ 89 | loop_count--; 90 | if (loop_count == 0){ 91 | break;// exit loop 92 | } 93 | } 94 | 95 | // Sleep 3 seconds 96 | //sleep(3); 97 | cur_slot_sent--; 98 | if (cur_slot_sent == 0){ 99 | usleep(sleep_time * 1000); 100 | cur_slot_sent = slot_send_count; 101 | } 102 | } 103 | 104 | if (!na->no_close){ 105 | close(sock_fd); 106 | } 107 | 108 | if (send_msg){ 109 | free_buffer(send_msg); 110 | send_msg = NULL; 111 | } 112 | 113 | return 0; 114 | } 115 | 116 | -------------------------------------------------------------------------------- /03-12_最简单的UDP客户端服务器/nwc_connection.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "nwc_connection.h" 4 | 5 | struct nwc_connection *alloc_nwc_conn_arg0() 6 | { 7 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 8 | 9 | nwc->next = nwc; 10 | nwc->prev = nwc; 11 | 12 | return nwc; 13 | } 14 | 15 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd) 16 | { 17 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 18 | 19 | nwc->next = nwc; 20 | nwc->prev = nwc; 21 | nwc->pid = pid; 22 | nwc->fd = fd; 23 | 24 | return nwc; 25 | } 26 | 27 | void free_nwc_conn(struct nwc_connection *nwc) 28 | { 29 | if (nwc){ 30 | free(nwc); 31 | nwc = NULL; 32 | } 33 | } 34 | 35 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr) 36 | { 37 | struct nwc_connection *nwc = hdr->next; 38 | struct sockaddr_in *dstaddr = (struct sockaddr_in*)addr; 39 | 40 | for (; nwc != hdr;nwc = nwc->next){ 41 | if (nwc->addr.sin_port == dstaddr->sin_port 42 | && nwc->addr.sin_addr.s_addr == dstaddr->sin_addr.s_addr) 43 | return nwc; 44 | } 45 | 46 | return NULL; 47 | } 48 | 49 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc) 50 | { 51 | struct nwc_connection *prev = hdr->prev; 52 | struct nwc_connection *next = hdr; 53 | nwc->prev = prev; 54 | nwc->next = next; 55 | prev->next = nwc; 56 | next->prev = nwc; 57 | } 58 | 59 | void remove_nwc(struct nwc_connection *nwc) 60 | { 61 | struct nwc_connection *prev = nwc->prev; 62 | struct nwc_connection *next = nwc->next; 63 | 64 | prev->next = next; 65 | next->prev = prev; 66 | } 67 | void destroy_all_nwc(struct nwc_connection *hdr) 68 | { 69 | struct nwc_connection *nwc = hdr->next; 70 | for (; nwc != hdr;){ 71 | struct nwc_connection *next = nwc->next; 72 | free_nwc_conn(nwc); 73 | nwc = next; 74 | } 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /03-12_最简单的UDP客户端服务器/nwc_connection.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_CONNECTION_H_ 2 | #define _NWC_CONNECTION_H_ 3 | 4 | #include 5 | #include 6 | #include // inet_addr() 7 | 8 | struct nwc_connection 9 | { 10 | struct nwc_connection *next; 11 | struct nwc_connection *prev; 12 | 13 | pid_t pid; 14 | int fd; 15 | int echo_mode; 16 | int sleep_time; 17 | struct sockaddr_in addr; 18 | }; 19 | 20 | #define INIT_NWC(nwc)\ 21 | do { \ 22 | (nwc)->next = (nwc);\ 23 | (nwc)->prev = (nwc);\ 24 | (nwc)->pid = 0;\ 25 | (nwc)->fd = -1;\ 26 | }while(0); 27 | 28 | struct nwc_connection *alloc_nwc_conn_arg0(); 29 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd); 30 | void free_nwc_conn(struct nwc_connection *nwc); 31 | 32 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr); 33 | 34 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc); 35 | void remove_nwc(struct nwc_connection *nwc); 36 | void destroy_all_nwc(struct nwc_connection *hdr); 37 | 38 | 39 | #endif//_NWC_CONNECTION_H_ 40 | 41 | -------------------------------------------------------------------------------- /03-12_最简单的UDP客户端服务器/nwchecker.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWCHECER_H_ 2 | #define _NWCHECER_H_ 3 | 4 | 5 | struct nwc_args 6 | { 7 | const char *ip; 8 | unsigned short port; 9 | int count; 10 | int no_close; 11 | int interval; // The unit is ms 12 | int sent_pkgs; // The sent packages of every slot. 13 | int message_size; // The send message size. 14 | int echo_mode; // 0:immediate, 1: random time, 2: no response, 3: server not recv 15 | int is_udp_connect; // The udp use connect() 16 | }; 17 | 18 | int nwc_client(struct nwc_args *na); 19 | int nwc_server(struct nwc_args *na); 20 | 21 | int nwc_udp_client(struct nwc_args *na); 22 | int nwc_udp_server(struct nwc_args *na); 23 | 24 | char * alloc_buffer(int alloc_size); 25 | void free_buffer(char *buff); 26 | 27 | 28 | #endif//_NWCHECER_H_ 29 | 30 | -------------------------------------------------------------------------------- /03-12_最简单的UDP客户端服务器/nwchecker_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include // inet_addr() 10 | 11 | #include "nwchecker.h" 12 | 13 | int nwc_client(struct nwc_args *na) 14 | { 15 | int rc = 0; 16 | int sock_fd = -1; 17 | struct sockaddr_in serveraddr; 18 | 19 | char *send_msg = NULL; 20 | size_t send_msg_len = 0; 21 | 22 | // Used to receive the "pong" message from the server. 23 | char recv_buffer[8] = {0}; 24 | 25 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); 26 | if (sock_fd == -1){ 27 | printf("Create socket failed! errno(%d)\n", errno); 28 | return -1; 29 | } 30 | 31 | memset(&serveraddr, 0, sizeof(serveraddr)); 32 | 33 | serveraddr.sin_family = AF_INET; 34 | serveraddr.sin_port = htons(na->port); 35 | serveraddr.sin_addr.s_addr = inet_addr(na->ip); 36 | 37 | rc = connect(sock_fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 38 | if (rc == -1){ 39 | printf("Connect server failed! errno(%d)\n", errno); 40 | return -1; 41 | } 42 | 43 | send_msg_len = na->message_size <= 0?5:na->message_size; 44 | send_msg = alloc_buffer(send_msg_len); 45 | 46 | useconds_t sleep_time = na->interval <= 0 ? 3000 : na->interval; 47 | int slot_send_count = na->sent_pkgs <= 0? 1: na->sent_pkgs; 48 | int cur_slot_sent = slot_send_count; 49 | int infinit = na->count <= 0 ? 1:0; 50 | int loop_count = na->count * slot_send_count; 51 | int echo_mode = na->echo_mode; 52 | 53 | printf("nwc client. slot_send_count(%d) infinit(%d) loop_count(%d) echo_mode(%d) sleep_time(%d)\n", 54 | slot_send_count, 55 | infinit, 56 | loop_count, 57 | echo_mode, 58 | sleep_time); 59 | 60 | while(1){ 61 | rc = send(sock_fd, send_msg, send_msg_len, 0); 62 | if (rc == -1){ 63 | printf("Send ping request failed! errno(%d)\n", errno); 64 | break; 65 | } 66 | 67 | if (send_msg_len <= 5){ 68 | printf("%ld Send %s to server!\n", time(NULL), send_msg); 69 | }else{ 70 | printf("%ld Send %ld message to server!\n", time(NULL), send_msg_len); 71 | } 72 | 73 | if (echo_mode != 2){ 74 | rc = recv(sock_fd, recv_buffer, 7, 0); 75 | if (rc == 0){ 76 | printf("The connection is closed by peer!\n"); 77 | break; 78 | } 79 | 80 | if (rc == -1){ 81 | printf("Receive message failed!errno(%d)\n", errno); 82 | break; 83 | } 84 | 85 | printf("%ld Recv %s from the server\n", time(NULL), recv_buffer); 86 | } 87 | 88 | if (!infinit){ 89 | loop_count--; 90 | if (loop_count == 0){ 91 | break;// exit loop 92 | } 93 | } 94 | 95 | // Sleep 3 seconds 96 | //sleep(3); 97 | cur_slot_sent--; 98 | if (cur_slot_sent == 0){ 99 | usleep(sleep_time * 1000); 100 | cur_slot_sent = slot_send_count; 101 | } 102 | } 103 | 104 | if (!na->no_close){ 105 | close(sock_fd); 106 | } 107 | 108 | if (send_msg){ 109 | free_buffer(send_msg); 110 | send_msg = NULL; 111 | } 112 | 113 | return 0; 114 | } 115 | 116 | -------------------------------------------------------------------------------- /03-13_UNIX域套接字编程/nwc_connection.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "nwc_connection.h" 4 | 5 | struct nwc_connection *alloc_nwc_conn_arg0() 6 | { 7 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 8 | 9 | nwc->next = nwc; 10 | nwc->prev = nwc; 11 | 12 | return nwc; 13 | } 14 | 15 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd) 16 | { 17 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 18 | 19 | nwc->next = nwc; 20 | nwc->prev = nwc; 21 | nwc->pid = pid; 22 | nwc->fd = fd; 23 | 24 | return nwc; 25 | } 26 | 27 | void free_nwc_conn(struct nwc_connection *nwc) 28 | { 29 | if (nwc){ 30 | free(nwc); 31 | nwc = NULL; 32 | } 33 | } 34 | 35 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr) 36 | { 37 | struct nwc_connection *nwc = hdr->next; 38 | struct sockaddr_in *dstaddr = (struct sockaddr_in*)addr; 39 | 40 | for (; nwc != hdr;nwc = nwc->next){ 41 | if (nwc->addr.sin_port == dstaddr->sin_port 42 | && nwc->addr.sin_addr.s_addr == dstaddr->sin_addr.s_addr) 43 | return nwc; 44 | } 45 | 46 | return NULL; 47 | } 48 | 49 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc) 50 | { 51 | struct nwc_connection *prev = hdr->prev; 52 | struct nwc_connection *next = hdr; 53 | nwc->prev = prev; 54 | nwc->next = next; 55 | prev->next = nwc; 56 | next->prev = nwc; 57 | } 58 | 59 | void remove_nwc(struct nwc_connection *nwc) 60 | { 61 | struct nwc_connection *prev = nwc->prev; 62 | struct nwc_connection *next = nwc->next; 63 | 64 | prev->next = next; 65 | next->prev = prev; 66 | } 67 | void destroy_all_nwc(struct nwc_connection *hdr) 68 | { 69 | struct nwc_connection *nwc = hdr->next; 70 | for (; nwc != hdr;){ 71 | struct nwc_connection *next = nwc->next; 72 | free_nwc_conn(nwc); 73 | nwc = next; 74 | } 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /03-13_UNIX域套接字编程/nwc_connection.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_CONNECTION_H_ 2 | #define _NWC_CONNECTION_H_ 3 | 4 | #include 5 | #include 6 | #include // inet_addr() 7 | 8 | struct nwc_connection 9 | { 10 | struct nwc_connection *next; 11 | struct nwc_connection *prev; 12 | 13 | pid_t pid; 14 | int fd; 15 | int echo_mode; 16 | int sleep_time; 17 | struct sockaddr_in addr; 18 | }; 19 | 20 | #define INIT_NWC(nwc)\ 21 | do { \ 22 | (nwc)->next = (nwc);\ 23 | (nwc)->prev = (nwc);\ 24 | (nwc)->pid = 0;\ 25 | (nwc)->fd = -1;\ 26 | }while(0); 27 | 28 | struct nwc_connection *alloc_nwc_conn_arg0(); 29 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd); 30 | void free_nwc_conn(struct nwc_connection *nwc); 31 | 32 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr); 33 | 34 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc); 35 | void remove_nwc(struct nwc_connection *nwc); 36 | void destroy_all_nwc(struct nwc_connection *hdr); 37 | 38 | 39 | #endif//_NWC_CONNECTION_H_ 40 | 41 | -------------------------------------------------------------------------------- /03-13_UNIX域套接字编程/nwchecker.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWCHECER_H_ 2 | #define _NWCHECER_H_ 3 | 4 | 5 | struct nwc_args 6 | { 7 | const char *ip; 8 | const char *localaddr; 9 | unsigned short port; 10 | int count; 11 | int no_close; 12 | int interval; // The unit is ms 13 | int sent_pkgs; // The sent packages of every slot. 14 | int message_size; // The send message size. 15 | int echo_mode; // 0:immediate, 1: random time, 2: no response, 3: server not recv 16 | int is_udp_connect; // The udp use connect() 17 | }; 18 | 19 | int nwc_client(struct nwc_args *na); 20 | int nwc_server(struct nwc_args *na); 21 | 22 | int nwc_udp_client(struct nwc_args *na); 23 | int nwc_udp_server(struct nwc_args *na); 24 | 25 | int unix_stream_client(struct nwc_args *na); 26 | int unix_stream_server(struct nwc_args *na); 27 | 28 | int unix_dgram_client(struct nwc_args *na); 29 | int unix_dgram_server(struct nwc_args *na); 30 | 31 | char * alloc_buffer(int alloc_size); 32 | void free_buffer(char *buff); 33 | 34 | 35 | #endif//_NWCHECER_H_ 36 | 37 | -------------------------------------------------------------------------------- /03-13_UNIX域套接字编程/unix_dgram_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | int unix_dgram_client(struct nwc_args *na) 11 | { 12 | int rc = -1; 13 | struct sockaddr_un serveraddr, localaddr; 14 | 15 | int fd = socket(AF_LOCAL, SOCK_DGRAM, 0); 16 | if (fd == -1){ 17 | printf("Create unix dgram socket failed!errno(%d)\n", errno); 18 | return -1; 19 | } 20 | 21 | memset(&localaddr, 0, sizeof(localaddr)); 22 | localaddr.sun_family = AF_LOCAL; 23 | strncpy(localaddr.sun_path, na->localaddr, sizeof(localaddr.sun_path) - 1); 24 | 25 | unlink(localaddr.sun_path); 26 | 27 | rc = bind(fd, (struct sockaddr*)&localaddr, sizeof(localaddr)); 28 | if (rc == -1){ 29 | printf("Bind unix local dgram addr failed!errno(%d)\n", errno); 30 | return -1; 31 | } 32 | 33 | memset(&serveraddr, 0, sizeof(serveraddr)); 34 | serveraddr.sun_family = AF_LOCAL; 35 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path) - 1); 36 | 37 | if (na->is_udp_connect){ 38 | rc = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 39 | if (rc == -1){ 40 | printf("Connect unix dgram server failed!errno(%d)\n", errno); 41 | return -1; 42 | } 43 | } 44 | 45 | while(1){ 46 | if (na->is_udp_connect){ 47 | rc = sendto(fd, "ping", 4, 0, NULL , 0); 48 | }else{ 49 | rc = sendto(fd, "ping", 4, 0, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 50 | } 51 | if (rc == -1){ 52 | printf("Send ping failed!errno(%d)\n", errno); 53 | break; 54 | } 55 | 56 | printf("Send ping request!\n"); 57 | char buff[5] = {0}; 58 | 59 | struct sockaddr_un peeraddr; 60 | socklen_t peeraddrlen = sizeof(peeraddr); 61 | memset(&peeraddr, 0, sizeof(peeraddr)); 62 | 63 | if (na->is_udp_connect){ 64 | rc = recvfrom(fd, buff, 4, 0, NULL, 0); 65 | }else{ 66 | rc = recvfrom(fd, buff, 4, 0, (struct sockaddr*)&peeraddr, &peeraddrlen); 67 | } 68 | if (rc <= 0){ 69 | printf("Recv pong failed!errno(%d) rc(%d)\n", errno, rc); 70 | break; 71 | } 72 | 73 | printf("Recv (%s) response!\n", buff); 74 | } 75 | 76 | return 0; 77 | } 78 | 79 | 80 | -------------------------------------------------------------------------------- /03-13_UNIX域套接字编程/unix_dgram_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | int unix_dgram_server(struct nwc_args *na) 11 | { 12 | int rc = -1; 13 | struct sockaddr_un serveraddr, peeraddr; 14 | socklen_t peeraddrlen; 15 | 16 | int fd = socket(AF_UNIX, SOCK_DGRAM, 0); 17 | if (fd == -1){ 18 | printf("Create unix dgram socket failed!errno(%d)\n", errno); 19 | return -1; 20 | } 21 | 22 | memset(&serveraddr, 0, sizeof(serveraddr)); 23 | 24 | serveraddr.sun_family = AF_UNIX; 25 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path)-1); 26 | unlink(serveraddr.sun_path); 27 | 28 | rc = bind(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 29 | if (rc == -1){ 30 | printf("Bind unix stream server failed!errno(%d)\n", errno); 31 | return -1; 32 | } 33 | 34 | 35 | while (1){ 36 | char buff[5] = {0}; 37 | memset(&peeraddr, 0, sizeof(peeraddr)); 38 | peeraddrlen = sizeof(peeraddr); 39 | rc = recvfrom(fd, buff, 4, 0, (struct sockaddr*)&peeraddr, &peeraddrlen); 40 | if (rc <= 0){ 41 | printf("Recv ping failed!errno(%d) rc(%d)\n", errno, rc); 42 | continue; 43 | } 44 | 45 | printf("Recv (%s) request!\n", buff); 46 | rc = sendto(fd, "pong", 4, 0, (struct sockaddr*)&peeraddr, peeraddrlen); 47 | if (rc == -1){ 48 | printf("Send pong failed!errno(%d)\n", errno); 49 | continue; 50 | } 51 | 52 | printf("Send pong response!\n"); 53 | } 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /03-13_UNIX域套接字编程/unix_stream_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "nwchecker.h" 10 | 11 | int unix_stream_client(struct nwc_args *na) 12 | { 13 | int rc = -1; 14 | struct sockaddr_un serveraddr; 15 | char *send_msg = NULL; 16 | size_t send_msg_len = 0; 17 | 18 | unsigned long total_send_size = 0; 19 | 20 | int fd = socket(AF_LOCAL, SOCK_STREAM, 0); 21 | if (fd == -1){ 22 | printf("Create unix sream socket failed!errno(%d)\n", errno); 23 | return -1; 24 | } 25 | 26 | memset(&serveraddr, 0, sizeof(serveraddr)); 27 | 28 | serveraddr.sun_family = AF_LOCAL; 29 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path) - 1); 30 | 31 | rc = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 32 | if (rc == -1){ 33 | printf("Connect unix stream server failed!errno(%d)\n", errno); 34 | return -1; 35 | } 36 | 37 | useconds_t sleep_time = na->interval <= 0 ? 3000 : na->interval; 38 | int slot_send_count = na->sent_pkgs <= 0? 1: na->sent_pkgs; 39 | int cur_slot_sent = slot_send_count; 40 | int infinit = na->count <= 0 ? 1:0; 41 | int loop_count = na->count * slot_send_count; 42 | 43 | send_msg_len = na->message_size <= 0?5:na->message_size; 44 | send_msg = alloc_buffer(send_msg_len); 45 | 46 | struct timespec start, end; 47 | clock_gettime(CLOCK_MONOTONIC, &start); 48 | 49 | while(1){ 50 | rc = send(fd, send_msg, send_msg_len, 0); 51 | if (rc == -1){ 52 | printf("Send ping failed!errno(%d)\n", errno); 53 | break; 54 | } 55 | 56 | total_send_size += send_msg_len; 57 | 58 | if (send_msg_len <= 5){ 59 | printf("Send ping request!\n"); 60 | } 61 | char buff[5] = {0}; 62 | rc = recv(fd, buff, 4, 0); 63 | if (rc <= 0){ 64 | printf("Recv pong failed!errno(%d) rc(%d)\n", errno, rc); 65 | break; 66 | } 67 | 68 | if (send_msg_len <= 5){ 69 | printf("Recv (%s) response!\n", buff); 70 | } 71 | 72 | if (!infinit){ 73 | loop_count--; 74 | if (loop_count == 0){ 75 | break;// exit loop 76 | } 77 | } 78 | 79 | cur_slot_sent--; 80 | if (cur_slot_sent == 0){ 81 | usleep(sleep_time * 1000); 82 | cur_slot_sent = slot_send_count; 83 | } 84 | } 85 | 86 | clock_gettime(CLOCK_MONOTONIC, &end); 87 | unsigned long secs = (end.tv_sec - start.tv_sec) + (end.tv_nsec-end.tv_nsec)/1000000000; 88 | unsigned long bytes_per_sec = total_send_size; 89 | 90 | if (secs > 0){ 91 | bytes_per_sec = total_send_size/secs; 92 | } 93 | 94 | printf("Send totalsize(%lu) secs(%lu) bytes_per_sec(%lu)\n", 95 | total_send_size, 96 | secs, 97 | bytes_per_sec); 98 | 99 | return 0; 100 | } 101 | 102 | 103 | -------------------------------------------------------------------------------- /03-13_UNIX域套接字编程/unix_stream_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | #define RECV_BUFF_LEN 4*1024*1024 11 | 12 | int unix_stream_server(struct nwc_args *na) 13 | { 14 | int rc = -1; 15 | struct sockaddr_un serveraddr; 16 | char *recv_buffer = NULL; 17 | 18 | int fd = socket(AF_UNIX, SOCK_STREAM, 0); 19 | if (fd == -1){ 20 | printf("Create unix sream socket failed!errno(%d)\n", errno); 21 | return -1; 22 | } 23 | 24 | memset(&serveraddr, 0, sizeof(serveraddr)); 25 | 26 | serveraddr.sun_family = AF_UNIX; 27 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path)-1); 28 | unlink(serveraddr.sun_path); 29 | 30 | rc = bind(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 31 | if (rc == -1){ 32 | printf("Bind unix stream server failed!errno(%d)\n", errno); 33 | return -1; 34 | } 35 | 36 | rc = listen(fd, 5); 37 | if (rc == -1){ 38 | printf("Listen unix stream server failed!errno(%d)\n", errno); 39 | return -1; 40 | } 41 | 42 | recv_buffer = alloc_buffer(RECV_BUFF_LEN); 43 | 44 | int output_log = 0; 45 | 46 | while (1){ 47 | int newfd = accept(fd, NULL, NULL); 48 | if (newfd == -1){ 49 | printf("Accept new unix stream server failed!fd(%d) errno(%d)\n", fd, errno); 50 | break; 51 | } 52 | 53 | printf("Accept a new unix stream fd(%d)\n", fd); 54 | 55 | if (fork() == 0){ 56 | close(fd); 57 | while(1){ 58 | char buff[5] = {0}; 59 | rc = recv(newfd, recv_buffer, RECV_BUFF_LEN, 0); 60 | if (rc <= 0){ 61 | printf("Recv ping failed!errno(%d) rc(%d)\n", errno, rc); 62 | break; 63 | } 64 | 65 | output_log = rc <= 5? 1:0; 66 | 67 | if (output_log){ 68 | printf("Recv (%s) request!\n", buff); 69 | } 70 | rc = send(newfd, "pong", 4, 0); 71 | if (rc == -1){ 72 | printf("Send pong failed!errno(%d)\n", errno); 73 | break; 74 | } 75 | 76 | if (output_log){ 77 | printf("Send pong response!\n"); 78 | } 79 | } 80 | close(newfd); 81 | _exit(0); 82 | }else{ 83 | close(newfd); 84 | } 85 | } 86 | 87 | if (recv_buffer){ 88 | free_buffer(recv_buffer); 89 | recv_buffer = NULL; 90 | } 91 | 92 | close(fd); 93 | 94 | return 0; 95 | } 96 | 97 | -------------------------------------------------------------------------------- /03-14_掌控你的Socket套接口/sock_option.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | struct sockopt_set 9 | { 10 | char *optname; 11 | int level; 12 | int opt; 13 | }; 14 | 15 | struct sockopt_set sockopts[] = { 16 | {"SO_ACCEPTCONN", SOL_SOCKET, SO_ACCEPTCONN}, 17 | {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST}, 18 | {"SO_DEBUG", SOL_SOCKET, SO_DEBUG}, 19 | {"SO_DONTROUTE", SOL_SOCKET, SO_DONTROUTE}, 20 | {"SO_ERROR", SOL_SOCKET, SO_ERROR}, 21 | {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE}, 22 | {"SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE}, 23 | {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF}, 24 | {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT}, 25 | {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR}, 26 | {"SO_SNDBUF",SOL_SOCKET, SO_SNDBUF}, 27 | {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT}, 28 | {"SO_TYPE", SOL_SOCKET, SO_TYPE}, 29 | 30 | {"IP_MULTICAST_LOOP", IPPROTO_IP, IP_MULTICAST_LOOP}, 31 | {"IP_MULTICAST_TTL", IPPROTO_IP, IP_MULTICAST_TTL}, 32 | {"IP_TTL", IPPROTO_IP, IP_TTL}, 33 | 34 | {"IPV6_MULTICAST_LOOP", IPPROTO_IPV6, IPV6_MULTICAST_LOOP}, 35 | {"IPV6_MULTICAST_HOPS", IPPROTO_IPV6, IPV6_MULTICAST_HOPS}, 36 | #ifdef TCP_DEFER_ACCEPT 37 | {"TCP_DEFER_ACCEPT", IPPROTO_TCP, TCP_DEFER_ACCEPT}, 38 | #endif 39 | #ifdef TCP_QUICKACK 40 | {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK}, 41 | #endif 42 | #ifdef TCP_CORK 43 | {"TCP_CORK", IPPROTO_TCP, TCP_CORK}, 44 | #endif 45 | {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY}, 46 | #ifdef UDP_CORK 47 | {"UDP_CORK ", IPPROTO_UDP, UDP_CORK} 48 | #endif 49 | {NULL, 0, 0} 50 | }; 51 | 52 | void show_int_value(int socktype) 53 | { 54 | int ENTRYS = sizeof(sockopts)/ sizeof(struct sockopt_set); 55 | 56 | for (int i=0; i < ENTRYS; ++i){ 57 | if (sockopts[i].optname == NULL) 58 | continue; 59 | 60 | int pf = AF_INET; 61 | if (sockopts[i].level == IPPROTO_IPV6){ 62 | pf = AF_INET6; 63 | } 64 | 65 | int fd = socket(pf, socktype, 0); 66 | if (fd == -1){ 67 | printf("invoke socket failed errno(%d) errstr(%s)\n", errno, strerror(errno)); 68 | continue; 69 | } 70 | 71 | int optval = 0; 72 | int optlen = sizeof(optval); 73 | int rc = getsockopt(fd, sockopts[i].level, sockopts[i].opt, &optval, &optlen); 74 | if (rc == 0){ 75 | printf("(%s) level(%d) opt(%d) optval(%d)\n", 76 | sockopts[i].optname, 77 | sockopts[i].level, 78 | sockopts[i].opt, 79 | optval); 80 | }else{ 81 | printf("Getsockopt(%s) failed errno(%d) errstr(%s)\n", 82 | sockopts[i].optname, 83 | errno, 84 | strerror(errno)); 85 | } 86 | } 87 | } 88 | 89 | 90 | int main(int argc, char *argv[]) 91 | { 92 | printf("Test Stream ######################\n"); 93 | // Test Stream 94 | show_int_value(SOCK_STREAM); 95 | 96 | printf("\n\nTest Dgram ######################\n"); 97 | // Test Dgram 98 | show_int_value(SOCK_DGRAM); 99 | 100 | return 0; 101 | } 102 | 103 | 104 | -------------------------------------------------------------------------------- /03-15_通过域名进行编程/domain_name_resolve.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void gethostbyname_case(const char *hostname) 9 | { 10 | struct hostent *host = NULL; 11 | 12 | host = gethostbyname(hostname); 13 | if (!host){ 14 | printf("gethostbyname(%s) failed! errno(%d) errorstr(%s)\n", 15 | hostname, errno, hstrerror(errno)); 16 | return; 17 | } 18 | 19 | printf("h_name(%s) h_addrtype(%d) h_length(%d)\n", 20 | host->h_name, // CNAME 21 | host->h_addrtype, // AF_INET 22 | host->h_length); // 4 bytes 23 | 24 | char **ptr = host->h_aliases; 25 | for (; *ptr != NULL;){ 26 | printf("aliases(%s)\n", *ptr++); 27 | } 28 | 29 | ptr = host->h_addr_list; 30 | for (; *ptr != NULL;){ 31 | char *addr = *ptr++; 32 | printf("addr(%s)\n", inet_ntoa(*((struct in_addr*)addr))); 33 | } 34 | } 35 | 36 | void gethostbyaddr_case(const char *ip) 37 | { 38 | struct hostent *host = NULL; 39 | struct in_addr addr; 40 | 41 | inet_aton(ip, &addr); 42 | 43 | host = gethostbyaddr(&addr, sizeof(addr), AF_INET); 44 | if (!host){ 45 | printf("gethostbyaddr(%s) failed! errno(%d) errorstr(%s)\n", 46 | ip, errno, hstrerror(errno)); 47 | return; 48 | } 49 | 50 | printf("ip(%s) domainname(%s)\n", ip, host->h_name); 51 | } 52 | 53 | void getaddrinfo_case(const char *hostname, const char *service) 54 | { 55 | struct addrinfo hints; 56 | struct addrinfo *result, *rp; 57 | int s; 58 | 59 | 60 | memset(&hints, 0, sizeof(struct addrinfo)); 61 | hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ 62 | hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ 63 | hints.ai_flags = 0; /* For wildcard IP address */ 64 | hints.ai_protocol = 0; /* Any protocol */ 65 | hints.ai_canonname = NULL; 66 | hints.ai_addr = NULL; 67 | hints.ai_next = NULL; 68 | 69 | s = getaddrinfo(hostname, service, &hints, &result); 70 | if (s != 0) { 71 | fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); 72 | return; 73 | } 74 | 75 | 76 | for (rp = result; rp != NULL; rp = rp->ai_next) { 77 | char buf[128] = {0}; 78 | if (rp->ai_family == AF_INET){ 79 | inet_ntop(rp->ai_family, &((struct sockaddr_in*)rp->ai_addr)->sin_addr, buf, 127); 80 | }else if (rp->ai_family == AF_INET6){ 81 | inet_ntop(rp->ai_family, &((struct sockaddr_in6*)rp->ai_addr)->sin6_addr, buf, 127); 82 | } 83 | 84 | printf("hostname(%s) service(%s) family(%d) socktype(%d) protocol(%d) addr(%s)\n", 85 | hostname, 86 | service, 87 | rp->ai_family, 88 | rp->ai_socktype, 89 | rp->ai_protocol, 90 | buf); 91 | } 92 | 93 | freeaddrinfo(result); /* No longer needed */ 94 | } 95 | 96 | int main(int argc, char *argv[]) 97 | { 98 | /* 99 | gethostbyname_case("www.baidu.com"); 100 | gethostbyname_case("www.google.com"); 101 | 102 | gethostbyaddr_case("114.114.114.114"); 103 | gethostbyaddr_case("4.4.4.4"); 104 | gethostbyaddr_case("8.8.8.8"); 105 | */ 106 | getaddrinfo_case("www.imooc.com", NULL); 107 | 108 | // getaddrinfo_case(NULL, "80"); 109 | 110 | return 0; 111 | } 112 | 113 | -------------------------------------------------------------------------------- /03-17_认识select和poll/poll_demo.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* According to earlier standards */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | void worker(int fd) 12 | { 13 | srand(fd); 14 | unsigned char num = 1; 15 | while(num++){ 16 | sleep((rand()% 5)+1); 17 | write(fd, &num, sizeof(num)); 18 | } 19 | close(fd); 20 | } 21 | 22 | int main(int argc, char *argv) 23 | { 24 | int sock_fds[3][2] = {-1}; 25 | int worker_exit[3] = {0}; 26 | pid_t worker_pids[3] = {0}; 27 | struct pollfd fds[3]; 28 | 29 | 30 | for (int i=0; i < 3; ++i){ 31 | if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sock_fds[i]) == -1){ 32 | printf("Invoke socketpair failed(%d)\n", errno); 33 | return -1; 34 | } 35 | } 36 | 37 | for (int i=0; i < 3; ++i){ 38 | pid_t pid = fork(); 39 | if (pid == 0){ 40 | close(sock_fds[i][1]); 41 | worker(sock_fds[i][0]); 42 | }else{ 43 | worker_pids[i] = pid; 44 | close(sock_fds[i][0]); 45 | } 46 | } 47 | 48 | 49 | while(1){ 50 | for (int i=0; i < 3; ++i){ 51 | fds[i].fd = sock_fds[i][1]; 52 | fds[i].events = POLLIN; 53 | fds[i].revents = 0; 54 | } 55 | 56 | int nfds = poll(fds, 3, -1); 57 | if (nfds == -1){ 58 | printf("Poll error(%d)\n", errno); 59 | break; 60 | } 61 | 62 | for (int i=0; i < 3; ++i){ 63 | if (fds[i].revents & POLLIN){ 64 | int num = 0; 65 | read(sock_fds[i][1], &num, sizeof(num)); 66 | printf("Master recv worker[%d:%d]: %d\n", worker_pids[i], sock_fds[i][1], num); 67 | if (num == 255){ 68 | worker_exit[i] = 1; 69 | } 70 | } 71 | } 72 | 73 | int exit_num=0; 74 | for (;exit_num < 3; ++exit_num){ 75 | if (!worker_exit[exit_num]) 76 | break; 77 | } 78 | // exit loop 79 | if (exit_num == 3) 80 | break; 81 | } 82 | 83 | for (int i = 0; i < 3; ++i){ 84 | waitpid(worker_pids[i], NULL, WUNTRACED); 85 | close(sock_fds[i][1]); 86 | } 87 | 88 | return 0; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /03-17_认识select和poll/select_demo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | void child_worker(int fd) 12 | { 13 | srand(fd); 14 | unsigned char num = 1; 15 | while(num++){ 16 | sleep((rand()% 5)+1); 17 | write(fd, &num, sizeof(num)); 18 | } 19 | close(fd); 20 | } 21 | 22 | int main(int argc, char *argv) 23 | { 24 | int sock_fds[3][2] = {-1}; 25 | fd_set readfds; 26 | int worker_exit[3] = {0}; 27 | pid_t worker_pids[3] = {0}; 28 | 29 | 30 | for (int i=0; i < 3; ++i){ 31 | if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sock_fds[i]) == -1){ 32 | printf("Invoke socketpair failed(%d)\n", errno); 33 | return -1; 34 | } 35 | } 36 | 37 | for (int i=0; i < 3; ++i){ 38 | pid_t pid = fork(); 39 | if (pid == 0){ 40 | close(sock_fds[i][1]); 41 | child_worker(sock_fds[i][0]); 42 | }else{ 43 | worker_pids[i] = pid; 44 | close(sock_fds[i][0]); 45 | } 46 | } 47 | 48 | while(1){ 49 | int maxfd = -1; 50 | FD_ZERO(&readfds); 51 | for (int i=0; i < 3; ++i){ 52 | FD_SET(sock_fds[i][1], &readfds); 53 | if (sock_fds[i][1] > maxfd) 54 | maxfd = sock_fds[i][1]; 55 | } 56 | 57 | int nfds = select(maxfd + 1, &readfds, NULL, NULL, NULL); 58 | if (nfds == -1){ 59 | printf("Select error(%d)\n", errno); 60 | if (errno == EINTR){ 61 | continue; 62 | } 63 | 64 | break; 65 | } 66 | 67 | for (int i=0; i < 3; ++i){ 68 | if (FD_ISSET(sock_fds[i][1], &readfds)){ 69 | int num = 0; 70 | read(sock_fds[i][1], &num, sizeof(num)); 71 | printf("Master recv worker[%d:%d]: %d\n", worker_pids[i], sock_fds[i][1], num); 72 | if (num == 255){ 73 | worker_exit[i] = 1; 74 | } 75 | } 76 | } 77 | 78 | int exit_num=0; 79 | for (;exit_num < 3; ++exit_num){ 80 | if (!worker_exit[exit_num]) 81 | break; 82 | } 83 | // exit loop 84 | if (exit_num == 3) 85 | break; 86 | } 87 | 88 | for (int i = 0; i < 3; ++i){ 89 | waitpid(worker_pids[i], NULL, WUNTRACED); 90 | close(sock_fds[i][1]); 91 | } 92 | 93 | return 0; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /03-18_非阻塞Socket编程/nwc_connection.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "nwc_connection.h" 5 | 6 | struct nwc_connection *alloc_nwc_conn_arg0() 7 | { 8 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 9 | 10 | nwc->next = nwc; 11 | nwc->prev = nwc; 12 | 13 | return nwc; 14 | } 15 | 16 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd) 17 | { 18 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 19 | 20 | nwc->next = nwc; 21 | nwc->prev = nwc; 22 | nwc->pid = pid; 23 | nwc->fd = fd; 24 | 25 | return nwc; 26 | } 27 | 28 | void free_nwc_conn(struct nwc_connection *nwc) 29 | { 30 | if (nwc){ 31 | if (nwc->recv_buffer){ 32 | free(nwc->recv_buffer); 33 | nwc->recv_buffer = NULL; 34 | } 35 | 36 | if (nwc->fd != -1){ 37 | close(nwc->fd); 38 | nwc->fd = -1; 39 | } 40 | 41 | free(nwc); 42 | nwc = NULL; 43 | } 44 | } 45 | 46 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr) 47 | { 48 | struct nwc_connection *nwc = hdr->next; 49 | struct sockaddr_in *dstaddr = (struct sockaddr_in*)addr; 50 | 51 | for (; nwc != hdr;nwc = nwc->next){ 52 | if (nwc->addr.sin_port == dstaddr->sin_port 53 | && nwc->addr.sin_addr.s_addr == dstaddr->sin_addr.s_addr) 54 | return nwc; 55 | } 56 | 57 | return NULL; 58 | } 59 | 60 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc) 61 | { 62 | struct nwc_connection *prev = hdr->prev; 63 | struct nwc_connection *next = hdr; 64 | nwc->prev = prev; 65 | nwc->next = next; 66 | prev->next = nwc; 67 | next->prev = nwc; 68 | } 69 | 70 | void remove_nwc(struct nwc_connection *nwc) 71 | { 72 | struct nwc_connection *prev = nwc->prev; 73 | struct nwc_connection *next = nwc->next; 74 | 75 | prev->next = next; 76 | next->prev = prev; 77 | } 78 | void destroy_all_nwc(struct nwc_connection *hdr) 79 | { 80 | struct nwc_connection *nwc = hdr->next; 81 | for (; nwc != hdr;){ 82 | struct nwc_connection *next = nwc->next; 83 | free_nwc_conn(nwc); 84 | nwc = next; 85 | } 86 | } 87 | 88 | 89 | -------------------------------------------------------------------------------- /03-18_非阻塞Socket编程/nwc_connection.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_CONNECTION_H_ 2 | #define _NWC_CONNECTION_H_ 3 | 4 | #include 5 | #include 6 | #include // inet_addr() 7 | 8 | struct nwc_connection 9 | { 10 | struct nwc_connection *next; 11 | struct nwc_connection *prev; 12 | 13 | pid_t pid; 14 | int fd; 15 | int events; 16 | int echo_mode; 17 | struct sockaddr_in addr; 18 | char *recv_buffer; 19 | }; 20 | 21 | #define INIT_NWC(nwc)\ 22 | do { \ 23 | (nwc)->next = (nwc);\ 24 | (nwc)->prev = (nwc);\ 25 | (nwc)->pid = 0;\ 26 | (nwc)->fd = -1;\ 27 | (nwc)->events = 0;\ 28 | (nwc)->recv_buffer = NULL;\ 29 | }while(0); 30 | 31 | struct nwc_connection *alloc_nwc_conn_arg0(); 32 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd); 33 | void free_nwc_conn(struct nwc_connection *nwc); 34 | 35 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr); 36 | 37 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc); 38 | void remove_nwc(struct nwc_connection *nwc); 39 | void destroy_all_nwc(struct nwc_connection *hdr); 40 | 41 | 42 | #endif//_NWC_CONNECTION_H_ 43 | 44 | -------------------------------------------------------------------------------- /03-18_非阻塞Socket编程/nwchecker.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWCHECER_H_ 2 | #define _NWCHECER_H_ 3 | 4 | 5 | struct nwc_args 6 | { 7 | const char *ip; 8 | const char *localaddr; 9 | unsigned short port; 10 | int count; 11 | int no_close; 12 | int interval; // The unit is ms 13 | int sent_pkgs; // The sent packages of every slot. 14 | int message_size; // The send message size. 15 | int echo_mode; // 0:immediate, 1: random time, 2: no response, 3: server not recv 16 | int is_udp_connect; // The udp use connect() 17 | }; 18 | 19 | int nwc_client(struct nwc_args *na); 20 | int nwc_server(struct nwc_args *na); 21 | 22 | int nwc_udp_client(struct nwc_args *na); 23 | int nwc_udp_server(struct nwc_args *na); 24 | 25 | int unix_stream_client(struct nwc_args *na); 26 | int unix_stream_server(struct nwc_args *na); 27 | 28 | int unix_dgram_client(struct nwc_args *na); 29 | int unix_dgram_server(struct nwc_args *na); 30 | 31 | char * alloc_buffer(int alloc_size); 32 | void free_buffer(char *buff); 33 | 34 | 35 | #endif//_NWCHECER_H_ 36 | 37 | -------------------------------------------------------------------------------- /03-18_非阻塞Socket编程/unix_dgram_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | int unix_dgram_client(struct nwc_args *na) 11 | { 12 | int rc = -1; 13 | struct sockaddr_un serveraddr, localaddr; 14 | 15 | int fd = socket(AF_LOCAL, SOCK_DGRAM, 0); 16 | if (fd == -1){ 17 | printf("Create unix dgram socket failed!errno(%d)\n", errno); 18 | return -1; 19 | } 20 | 21 | memset(&localaddr, 0, sizeof(localaddr)); 22 | localaddr.sun_family = AF_LOCAL; 23 | strncpy(localaddr.sun_path, na->localaddr, sizeof(localaddr.sun_path) - 1); 24 | 25 | unlink(localaddr.sun_path); 26 | 27 | rc = bind(fd, (struct sockaddr*)&localaddr, sizeof(localaddr)); 28 | if (rc == -1){ 29 | printf("Bind unix local dgram addr failed!errno(%d)\n", errno); 30 | close(fd); 31 | return -1; 32 | } 33 | 34 | memset(&serveraddr, 0, sizeof(serveraddr)); 35 | serveraddr.sun_family = AF_LOCAL; 36 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path) - 1); 37 | 38 | if (na->is_udp_connect){ 39 | rc = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 40 | if (rc == -1){ 41 | printf("Connect unix dgram server failed!errno(%d)\n", errno); 42 | close(fd); 43 | return -1; 44 | } 45 | } 46 | 47 | while(1){ 48 | if (na->is_udp_connect){ 49 | rc = sendto(fd, "ping", 4, 0, NULL , 0); 50 | }else{ 51 | rc = sendto(fd, "ping", 4, 0, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 52 | } 53 | if (rc == -1){ 54 | printf("Send ping failed!errno(%d)\n", errno); 55 | break; 56 | } 57 | 58 | printf("Send ping request!\n"); 59 | char buff[5] = {0}; 60 | 61 | struct sockaddr_un peeraddr; 62 | socklen_t peeraddrlen = sizeof(peeraddr); 63 | memset(&peeraddr, 0, sizeof(peeraddr)); 64 | 65 | if (na->is_udp_connect){ 66 | rc = recvfrom(fd, buff, 4, 0, NULL, 0); 67 | }else{ 68 | rc = recvfrom(fd, buff, 4, 0, (struct sockaddr*)&peeraddr, &peeraddrlen); 69 | } 70 | if (rc <= 0){ 71 | printf("Recv pong failed!errno(%d) rc(%d)\n", errno, rc); 72 | break; 73 | } 74 | 75 | printf("Recv (%s) response!\n", buff); 76 | } 77 | 78 | close(fd); 79 | 80 | return 0; 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /03-18_非阻塞Socket编程/unix_dgram_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | int unix_dgram_server(struct nwc_args *na) 11 | { 12 | int rc = -1; 13 | struct sockaddr_un serveraddr, peeraddr; 14 | socklen_t peeraddrlen; 15 | 16 | int fd = socket(AF_UNIX, SOCK_DGRAM, 0); 17 | if (fd == -1){ 18 | printf("Create unix dgram socket failed!errno(%d)\n", errno); 19 | return -1; 20 | } 21 | 22 | memset(&serveraddr, 0, sizeof(serveraddr)); 23 | 24 | serveraddr.sun_family = AF_UNIX; 25 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path)-1); 26 | unlink(serveraddr.sun_path); 27 | 28 | rc = bind(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 29 | if (rc == -1){ 30 | printf("Bind unix stream server failed!errno(%d)\n", errno); 31 | close(fd); 32 | return -1; 33 | } 34 | 35 | 36 | while (1){ 37 | char buff[5] = {0}; 38 | memset(&peeraddr, 0, sizeof(peeraddr)); 39 | peeraddrlen = sizeof(peeraddr); 40 | rc = recvfrom(fd, buff, 4, 0, (struct sockaddr*)&peeraddr, &peeraddrlen); 41 | if (rc <= 0){ 42 | printf("Recv ping failed!errno(%d) rc(%d)\n", errno, rc); 43 | continue; 44 | } 45 | 46 | printf("Recv (%s) request!\n", buff); 47 | rc = sendto(fd, "pong", 4, 0, (struct sockaddr*)&peeraddr, peeraddrlen); 48 | if (rc == -1){ 49 | printf("Send pong failed!errno(%d)\n", errno); 50 | continue; 51 | } 52 | 53 | printf("Send pong response!\n"); 54 | } 55 | 56 | close(fd); 57 | 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /03-18_非阻塞Socket编程/unix_stream_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "nwchecker.h" 10 | 11 | int unix_stream_client(struct nwc_args *na) 12 | { 13 | int rc = -1; 14 | struct sockaddr_un serveraddr; 15 | char *send_msg = NULL; 16 | size_t send_msg_len = 0; 17 | 18 | unsigned long total_send_size = 0; 19 | 20 | int fd = socket(AF_LOCAL, SOCK_STREAM, 0); 21 | if (fd == -1){ 22 | printf("Create unix sream socket failed!errno(%d)\n", errno); 23 | return -1; 24 | } 25 | 26 | memset(&serveraddr, 0, sizeof(serveraddr)); 27 | 28 | serveraddr.sun_family = AF_LOCAL; 29 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path) - 1); 30 | 31 | rc = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 32 | if (rc == -1){ 33 | printf("Connect unix stream server failed!errno(%d)\n", errno); 34 | close(fd); 35 | return -1; 36 | } 37 | 38 | useconds_t sleep_time = na->interval <= 0 ? 3000 : na->interval; 39 | int slot_send_count = na->sent_pkgs <= 0? 1: na->sent_pkgs; 40 | int cur_slot_sent = slot_send_count; 41 | int infinit = na->count <= 0 ? 1:0; 42 | int loop_count = na->count * slot_send_count; 43 | 44 | send_msg_len = na->message_size <= 0?5:na->message_size; 45 | send_msg = alloc_buffer(send_msg_len); 46 | 47 | struct timespec start, end; 48 | clock_gettime(CLOCK_MONOTONIC, &start); 49 | 50 | while(1){ 51 | rc = send(fd, send_msg, send_msg_len, 0); 52 | if (rc == -1){ 53 | printf("Send ping failed!errno(%d)\n", errno); 54 | break; 55 | } 56 | 57 | total_send_size += send_msg_len; 58 | 59 | if (send_msg_len <= 5){ 60 | printf("Send ping request!\n"); 61 | } 62 | char buff[5] = {0}; 63 | rc = recv(fd, buff, 4, 0); 64 | if (rc <= 0){ 65 | printf("Recv pong failed!errno(%d) rc(%d)\n", errno, rc); 66 | break; 67 | } 68 | 69 | if (send_msg_len <= 5){ 70 | printf("Recv (%s) response!\n", buff); 71 | } 72 | 73 | if (!infinit){ 74 | loop_count--; 75 | if (loop_count == 0){ 76 | break;// exit loop 77 | } 78 | } 79 | 80 | cur_slot_sent--; 81 | if (cur_slot_sent == 0){ 82 | usleep(sleep_time * 1000); 83 | cur_slot_sent = slot_send_count; 84 | } 85 | } 86 | 87 | clock_gettime(CLOCK_MONOTONIC, &end); 88 | unsigned long secs = (end.tv_sec - start.tv_sec) + (end.tv_nsec-end.tv_nsec)/1000000000; 89 | unsigned long bytes_per_sec = total_send_size; 90 | 91 | if (secs > 0){ 92 | bytes_per_sec = total_send_size/secs; 93 | } 94 | 95 | printf("Send totalsize(%lu) secs(%lu) bytes_per_sec(%lu)\n", 96 | total_send_size, 97 | secs, 98 | bytes_per_sec); 99 | 100 | close(fd); 101 | 102 | return 0; 103 | } 104 | 105 | 106 | -------------------------------------------------------------------------------- /03-18_非阻塞Socket编程/unix_stream_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | #define RECV_BUFF_LEN 4*1024*1024 11 | 12 | int unix_stream_server(struct nwc_args *na) 13 | { 14 | int rc = -1; 15 | struct sockaddr_un serveraddr; 16 | char *recv_buffer = NULL; 17 | 18 | int fd = socket(AF_UNIX, SOCK_STREAM, 0); 19 | if (fd == -1){ 20 | printf("Create unix sream socket failed!errno(%d)\n", errno); 21 | return -1; 22 | } 23 | 24 | memset(&serveraddr, 0, sizeof(serveraddr)); 25 | 26 | serveraddr.sun_family = AF_UNIX; 27 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path)-1); 28 | unlink(serveraddr.sun_path); 29 | 30 | rc = bind(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 31 | if (rc == -1){ 32 | printf("Bind unix stream server failed!errno(%d)\n", errno); 33 | return -1; 34 | } 35 | 36 | rc = listen(fd, 5); 37 | if (rc == -1){ 38 | printf("Listen unix stream server failed!errno(%d)\n", errno); 39 | return -1; 40 | } 41 | 42 | recv_buffer = alloc_buffer(RECV_BUFF_LEN); 43 | 44 | int output_log = 0; 45 | 46 | while (1){ 47 | int newfd = accept(fd, NULL, NULL); 48 | if (newfd == -1){ 49 | printf("Accept new unix stream server failed!fd(%d) errno(%d)\n", fd, errno); 50 | break; 51 | } 52 | 53 | printf("Accept a new unix stream fd(%d)\n", fd); 54 | 55 | if (fork() == 0){ 56 | close(fd); 57 | while(1){ 58 | char buff[5] = {0}; 59 | rc = recv(newfd, recv_buffer, RECV_BUFF_LEN, 0); 60 | if (rc <= 0){ 61 | printf("Recv ping failed!errno(%d) rc(%d)\n", errno, rc); 62 | break; 63 | } 64 | 65 | output_log = rc <= 5? 1:0; 66 | 67 | if (output_log){ 68 | printf("Recv (%s) request!\n", buff); 69 | } 70 | rc = send(newfd, "pong", 4, 0); 71 | if (rc == -1){ 72 | printf("Send pong failed!errno(%d)\n", errno); 73 | break; 74 | } 75 | 76 | if (output_log){ 77 | printf("Send pong response!\n"); 78 | } 79 | } 80 | close(newfd); 81 | _exit(0); 82 | }else{ 83 | close(newfd); 84 | } 85 | } 86 | 87 | if (recv_buffer){ 88 | free_buffer(recv_buffer); 89 | recv_buffer = NULL; 90 | } 91 | 92 | close(fd); 93 | 94 | return 0; 95 | } 96 | 97 | -------------------------------------------------------------------------------- /03-19_理解linux_epoll的工作原理/nwc_connection.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "nwc_connection.h" 4 | 5 | struct nwc_connection *alloc_nwc_conn_arg0() 6 | { 7 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 8 | 9 | nwc->next = nwc; 10 | nwc->prev = nwc; 11 | 12 | return nwc; 13 | } 14 | 15 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd) 16 | { 17 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 18 | 19 | nwc->next = nwc; 20 | nwc->prev = nwc; 21 | nwc->pid = pid; 22 | nwc->fd = fd; 23 | 24 | return nwc; 25 | } 26 | 27 | void free_nwc_conn(struct nwc_connection *nwc) 28 | { 29 | if (nwc){ 30 | if (nwc->recv_buffer){ 31 | free(nwc->recv_buffer); 32 | nwc->recv_buffer = NULL; 33 | } 34 | 35 | if (nwc->fd != -1){ 36 | close(nwc->fd); 37 | nwc->fd = -1; 38 | } 39 | free(nwc); 40 | nwc = NULL; 41 | } 42 | } 43 | 44 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr) 45 | { 46 | struct nwc_connection *nwc = hdr->next; 47 | struct sockaddr_in *dstaddr = (struct sockaddr_in*)addr; 48 | 49 | for (; nwc != hdr;nwc = nwc->next){ 50 | if (nwc->addr.sin_port == dstaddr->sin_port 51 | && nwc->addr.sin_addr.s_addr == dstaddr->sin_addr.s_addr) 52 | return nwc; 53 | } 54 | 55 | return NULL; 56 | } 57 | 58 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc) 59 | { 60 | struct nwc_connection *prev = hdr->prev; 61 | struct nwc_connection *next = hdr; 62 | nwc->prev = prev; 63 | nwc->next = next; 64 | prev->next = nwc; 65 | next->prev = nwc; 66 | } 67 | 68 | void remove_nwc(struct nwc_connection *nwc) 69 | { 70 | struct nwc_connection *prev = nwc->prev; 71 | struct nwc_connection *next = nwc->next; 72 | 73 | prev->next = next; 74 | next->prev = prev; 75 | } 76 | void destroy_all_nwc(struct nwc_connection *hdr) 77 | { 78 | struct nwc_connection *nwc = hdr->next; 79 | for (; nwc != hdr;){ 80 | struct nwc_connection *next = nwc->next; 81 | free_nwc_conn(nwc); 82 | nwc = next; 83 | } 84 | } 85 | 86 | 87 | -------------------------------------------------------------------------------- /03-19_理解linux_epoll的工作原理/nwc_connection.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_CONNECTION_H_ 2 | #define _NWC_CONNECTION_H_ 3 | 4 | #include 5 | #include 6 | #include // inet_addr() 7 | 8 | struct nwc_connection 9 | { 10 | struct nwc_connection *next; 11 | struct nwc_connection *prev; 12 | 13 | pid_t pid; 14 | int fd; 15 | int events; 16 | int echo_mode; 17 | struct sockaddr_in addr; 18 | char *recv_buffer; 19 | }; 20 | 21 | #define INIT_NWC(nwc)\ 22 | do { \ 23 | (nwc)->next = (nwc);\ 24 | (nwc)->prev = (nwc);\ 25 | (nwc)->pid = 0;\ 26 | (nwc)->fd = -1;\ 27 | (nwc)->events = 0;\ 28 | (nwc)->recv_buffer = NULL;\ 29 | }while(0); 30 | 31 | struct nwc_connection *alloc_nwc_conn_arg0(); 32 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd); 33 | void free_nwc_conn(struct nwc_connection *nwc); 34 | 35 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr); 36 | 37 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc); 38 | void remove_nwc(struct nwc_connection *nwc); 39 | void destroy_all_nwc(struct nwc_connection *hdr); 40 | 41 | 42 | #endif//_NWC_CONNECTION_H_ 43 | 44 | -------------------------------------------------------------------------------- /03-19_理解linux_epoll的工作原理/nwchecker.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWCHECER_H_ 2 | #define _NWCHECER_H_ 3 | 4 | 5 | struct nwc_args 6 | { 7 | const char *ip; 8 | const char *localaddr; 9 | unsigned short port; 10 | int count; 11 | int no_close; 12 | int interval; // The unit is ms 13 | int sent_pkgs; // The sent packages of every slot. 14 | int message_size; // The send message size. 15 | int echo_mode; // 0:immediate, 1: random time, 2: no response, 3: server not recv 16 | int is_udp_connect; // The udp use connect() 17 | }; 18 | 19 | int nwc_client(struct nwc_args *na); 20 | int nwc_server(struct nwc_args *na); 21 | 22 | int nwc_udp_client(struct nwc_args *na); 23 | int nwc_udp_server(struct nwc_args *na); 24 | 25 | int unix_stream_client(struct nwc_args *na); 26 | int unix_stream_server(struct nwc_args *na); 27 | 28 | int unix_dgram_client(struct nwc_args *na); 29 | int unix_dgram_server(struct nwc_args *na); 30 | 31 | char * alloc_buffer(int alloc_size); 32 | void free_buffer(char *buff); 33 | 34 | 35 | #endif//_NWCHECER_H_ 36 | 37 | -------------------------------------------------------------------------------- /03-19_理解linux_epoll的工作原理/unix_dgram_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | int unix_dgram_client(struct nwc_args *na) 11 | { 12 | int rc = -1; 13 | struct sockaddr_un serveraddr, localaddr; 14 | 15 | int fd = socket(AF_LOCAL, SOCK_DGRAM, 0); 16 | if (fd == -1){ 17 | printf("Create unix dgram socket failed!errno(%d)\n", errno); 18 | return -1; 19 | } 20 | 21 | memset(&localaddr, 0, sizeof(localaddr)); 22 | localaddr.sun_family = AF_LOCAL; 23 | strncpy(localaddr.sun_path, na->localaddr, sizeof(localaddr.sun_path) - 1); 24 | 25 | unlink(localaddr.sun_path); 26 | 27 | rc = bind(fd, (struct sockaddr*)&localaddr, sizeof(localaddr)); 28 | if (rc == -1){ 29 | printf("Bind unix local dgram addr failed!errno(%d)\n", errno); 30 | close(fd); 31 | return -1; 32 | } 33 | 34 | memset(&serveraddr, 0, sizeof(serveraddr)); 35 | serveraddr.sun_family = AF_LOCAL; 36 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path) - 1); 37 | 38 | if (na->is_udp_connect){ 39 | rc = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 40 | if (rc == -1){ 41 | printf("Connect unix dgram server failed!errno(%d)\n", errno); 42 | close(fd); 43 | return -1; 44 | } 45 | } 46 | 47 | while(1){ 48 | if (na->is_udp_connect){ 49 | rc = sendto(fd, "ping", 4, 0, NULL , 0); 50 | }else{ 51 | rc = sendto(fd, "ping", 4, 0, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 52 | } 53 | if (rc == -1){ 54 | printf("Send ping failed!errno(%d)\n", errno); 55 | break; 56 | } 57 | 58 | printf("Send ping request!\n"); 59 | char buff[5] = {0}; 60 | 61 | struct sockaddr_un peeraddr; 62 | socklen_t peeraddrlen = sizeof(peeraddr); 63 | memset(&peeraddr, 0, sizeof(peeraddr)); 64 | 65 | if (na->is_udp_connect){ 66 | rc = recvfrom(fd, buff, 4, 0, NULL, 0); 67 | }else{ 68 | rc = recvfrom(fd, buff, 4, 0, (struct sockaddr*)&peeraddr, &peeraddrlen); 69 | } 70 | if (rc <= 0){ 71 | printf("Recv pong failed!errno(%d) rc(%d)\n", errno, rc); 72 | break; 73 | } 74 | 75 | printf("Recv (%s) response!\n", buff); 76 | } 77 | 78 | close(fd); 79 | 80 | return 0; 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /03-19_理解linux_epoll的工作原理/unix_dgram_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | int unix_dgram_server(struct nwc_args *na) 11 | { 12 | int rc = -1; 13 | struct sockaddr_un serveraddr, peeraddr; 14 | socklen_t peeraddrlen; 15 | 16 | int fd = socket(AF_UNIX, SOCK_DGRAM, 0); 17 | if (fd == -1){ 18 | printf("Create unix dgram socket failed!errno(%d)\n", errno); 19 | return -1; 20 | } 21 | 22 | memset(&serveraddr, 0, sizeof(serveraddr)); 23 | 24 | serveraddr.sun_family = AF_UNIX; 25 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path)-1); 26 | unlink(serveraddr.sun_path); 27 | 28 | rc = bind(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 29 | if (rc == -1){ 30 | printf("Bind unix stream server failed!errno(%d)\n", errno); 31 | close(fd); 32 | return -1; 33 | } 34 | 35 | 36 | while (1){ 37 | char buff[5] = {0}; 38 | memset(&peeraddr, 0, sizeof(peeraddr)); 39 | peeraddrlen = sizeof(peeraddr); 40 | rc = recvfrom(fd, buff, 4, 0, (struct sockaddr*)&peeraddr, &peeraddrlen); 41 | if (rc <= 0){ 42 | printf("Recv ping failed!errno(%d) rc(%d)\n", errno, rc); 43 | continue; 44 | } 45 | 46 | printf("Recv (%s) request!\n", buff); 47 | rc = sendto(fd, "pong", 4, 0, (struct sockaddr*)&peeraddr, peeraddrlen); 48 | if (rc == -1){ 49 | printf("Send pong failed!errno(%d)\n", errno); 50 | continue; 51 | } 52 | 53 | printf("Send pong response!\n"); 54 | } 55 | 56 | close(fd); 57 | 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /03-19_理解linux_epoll的工作原理/unix_stream_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "nwchecker.h" 10 | 11 | int unix_stream_client(struct nwc_args *na) 12 | { 13 | int rc = -1; 14 | struct sockaddr_un serveraddr; 15 | char *send_msg = NULL; 16 | size_t send_msg_len = 0; 17 | 18 | unsigned long total_send_size = 0; 19 | 20 | int fd = socket(AF_LOCAL, SOCK_STREAM, 0); 21 | if (fd == -1){ 22 | printf("Create unix sream socket failed!errno(%d)\n", errno); 23 | return -1; 24 | } 25 | 26 | memset(&serveraddr, 0, sizeof(serveraddr)); 27 | 28 | serveraddr.sun_family = AF_LOCAL; 29 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path) - 1); 30 | 31 | rc = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 32 | if (rc == -1){ 33 | printf("Connect unix stream server failed!errno(%d)\n", errno); 34 | close(fd); 35 | return -1; 36 | } 37 | 38 | useconds_t sleep_time = na->interval <= 0 ? 3000 : na->interval; 39 | int slot_send_count = na->sent_pkgs <= 0? 1: na->sent_pkgs; 40 | int cur_slot_sent = slot_send_count; 41 | int infinit = na->count <= 0 ? 1:0; 42 | int loop_count = na->count * slot_send_count; 43 | 44 | send_msg_len = na->message_size <= 0?5:na->message_size; 45 | send_msg = alloc_buffer(send_msg_len); 46 | 47 | struct timespec start, end; 48 | clock_gettime(CLOCK_MONOTONIC, &start); 49 | 50 | while(1){ 51 | rc = send(fd, send_msg, send_msg_len, 0); 52 | if (rc == -1){ 53 | printf("Send ping failed!errno(%d)\n", errno); 54 | break; 55 | } 56 | 57 | total_send_size += send_msg_len; 58 | 59 | if (send_msg_len <= 5){ 60 | printf("Send ping request!\n"); 61 | } 62 | char buff[5] = {0}; 63 | rc = recv(fd, buff, 4, 0); 64 | if (rc <= 0){ 65 | printf("Recv pong failed!errno(%d) rc(%d)\n", errno, rc); 66 | break; 67 | } 68 | 69 | if (send_msg_len <= 5){ 70 | printf("Recv (%s) response!\n", buff); 71 | } 72 | 73 | if (!infinit){ 74 | loop_count--; 75 | if (loop_count == 0){ 76 | break;// exit loop 77 | } 78 | } 79 | 80 | cur_slot_sent--; 81 | if (cur_slot_sent == 0){ 82 | usleep(sleep_time * 1000); 83 | cur_slot_sent = slot_send_count; 84 | } 85 | } 86 | 87 | clock_gettime(CLOCK_MONOTONIC, &end); 88 | unsigned long secs = (end.tv_sec - start.tv_sec) + (end.tv_nsec-end.tv_nsec)/1000000000; 89 | unsigned long bytes_per_sec = total_send_size; 90 | 91 | if (secs > 0){ 92 | bytes_per_sec = total_send_size/secs; 93 | } 94 | 95 | printf("Send totalsize(%lu) secs(%lu) bytes_per_sec(%lu)\n", 96 | total_send_size, 97 | secs, 98 | bytes_per_sec); 99 | 100 | close(fd); 101 | 102 | return 0; 103 | } 104 | 105 | 106 | -------------------------------------------------------------------------------- /03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/.vs/wsaselectdemo/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haska1025/imooc-sock-core-tech/b315bc1c3699fdc53feb6d86068be0f8642c7051/03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/.vs/wsaselectdemo/v14/.suo -------------------------------------------------------------------------------- /03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/wsaselectdemo.VC.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haska1025/imooc-sock-core-tech/b315bc1c3699fdc53feb6d86068be0f8642c7051/03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/wsaselectdemo.VC.db -------------------------------------------------------------------------------- /03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/wsaselectdemo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wsaselectdemo_client", "wsaselectdemo_client\wsaselectdemo_client.vcxproj", "{11B19F46-BA9E-4FC4-BC5A-D7C2C47477B5}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wsaselectdemo_server", "wsaselectdemo_server\wsaselectdemo_server.vcxproj", "{C118A95C-F9F7-4A5D-B0BA-A67FC447E102}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {11B19F46-BA9E-4FC4-BC5A-D7C2C47477B5}.Debug|x64.ActiveCfg = Debug|x64 19 | {11B19F46-BA9E-4FC4-BC5A-D7C2C47477B5}.Debug|x64.Build.0 = Debug|x64 20 | {11B19F46-BA9E-4FC4-BC5A-D7C2C47477B5}.Debug|x86.ActiveCfg = Debug|Win32 21 | {11B19F46-BA9E-4FC4-BC5A-D7C2C47477B5}.Debug|x86.Build.0 = Debug|Win32 22 | {11B19F46-BA9E-4FC4-BC5A-D7C2C47477B5}.Release|x64.ActiveCfg = Release|x64 23 | {11B19F46-BA9E-4FC4-BC5A-D7C2C47477B5}.Release|x64.Build.0 = Release|x64 24 | {11B19F46-BA9E-4FC4-BC5A-D7C2C47477B5}.Release|x86.ActiveCfg = Release|Win32 25 | {11B19F46-BA9E-4FC4-BC5A-D7C2C47477B5}.Release|x86.Build.0 = Release|Win32 26 | {C118A95C-F9F7-4A5D-B0BA-A67FC447E102}.Debug|x64.ActiveCfg = Debug|x64 27 | {C118A95C-F9F7-4A5D-B0BA-A67FC447E102}.Debug|x64.Build.0 = Debug|x64 28 | {C118A95C-F9F7-4A5D-B0BA-A67FC447E102}.Debug|x86.ActiveCfg = Debug|Win32 29 | {C118A95C-F9F7-4A5D-B0BA-A67FC447E102}.Debug|x86.Build.0 = Debug|Win32 30 | {C118A95C-F9F7-4A5D-B0BA-A67FC447E102}.Release|x64.ActiveCfg = Release|x64 31 | {C118A95C-F9F7-4A5D-B0BA-A67FC447E102}.Release|x64.Build.0 = Release|x64 32 | {C118A95C-F9F7-4A5D-B0BA-A67FC447E102}.Release|x86.ActiveCfg = Release|Win32 33 | {C118A95C-F9F7-4A5D-B0BA-A67FC447E102}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/wsaselectdemo_client/nwchecker_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | int rc = 0; 11 | SOCKET sock_fd = -1; 12 | struct sockaddr_in serveraddr; 13 | 14 | char *send_msg = "ping"; 15 | int send_msg_len = 4; 16 | 17 | // Used to receive the "pong" message from the server. 18 | char recv_buffer[8] = {0}; 19 | WSADATA wsaData = { 0 }; 20 | unsigned short port = 800; 21 | const char *serverip = "127.0.0.1"; 22 | 23 | if (argc < 3) { 24 | printf("You must input ip and port!\n"); 25 | return -1; 26 | } 27 | 28 | serverip = argv[1]; 29 | port = atoi(argv[2]); 30 | 31 | rc = WSAStartup(MAKEWORD(2, 2), &wsaData); 32 | if (rc != 0) { 33 | wprintf(L"WSAStartup failed: %d\n", rc); 34 | return 1; 35 | } 36 | 37 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); 38 | if (sock_fd == INVALID_SOCKET){ 39 | printf("Create socket failed! errno(%d)\n", WSAGetLastError()); 40 | return -1; 41 | } 42 | 43 | memset(&serveraddr, 0, sizeof(serveraddr)); 44 | 45 | serveraddr.sin_family = AF_INET; 46 | serveraddr.sin_port = htons(port); 47 | serveraddr.sin_addr.s_addr = inet_addr(serverip); 48 | 49 | rc = connect(sock_fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 50 | if (rc == SOCKET_ERROR){ 51 | printf("Connect server failed! errno(%d)\n", WSAGetLastError()); 52 | return -1; 53 | } 54 | 55 | while (1) { 56 | rc = send(sock_fd, send_msg, send_msg_len, 0); 57 | if (rc == SOCKET_ERROR) { 58 | printf("Send ping request failed! errno(%d)\n", WSAGetLastError()); 59 | break; 60 | } 61 | 62 | printf("%ld Send %s to server!\n", time(NULL), send_msg); 63 | 64 | rc = recv(sock_fd, recv_buffer, 7, 0); 65 | if (rc == 0) { 66 | printf("The connection is closed by peer!\n"); 67 | break; 68 | } 69 | 70 | if (rc == SOCKET_ERROR) { 71 | printf("Receive message failed!errno(%d)\n", WSAGetLastError()); 72 | break; 73 | } 74 | 75 | printf("%ld Recv %s from the server\n", time(NULL), recv_buffer); 76 | 77 | // Sleep 3 seconds 78 | Sleep(3000); 79 | } 80 | 81 | closesocket(sock_fd); 82 | 83 | return 0; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/wsaselectdemo_client/wsaselectdemo_client.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/wsaselectdemo_client/wsaselectdemo_client.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 127.0.0.1 800 5 | WindowsLocalDebugger 6 | 7 | -------------------------------------------------------------------------------- /03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/wsaselectdemo_server/nwchecker_server.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haska1025/imooc-sock-core-tech/b315bc1c3699fdc53feb6d86068be0f8642c7051/03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/wsaselectdemo_server/nwchecker_server.c -------------------------------------------------------------------------------- /03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/wsaselectdemo_server/wsaselectdemo_server.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /03-21_理解Windows_WSASelect的工作原理/wsaselectdemo/wsaselectdemo_server/wsaselectdemo_server.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 800 5 | WindowsLocalDebugger 6 | 7 | -------------------------------------------------------------------------------- /04-23_高级IO函数/nwc_connection.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "nwc_connection.h" 4 | 5 | struct nwc_connection *alloc_nwc_conn_arg0() 6 | { 7 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 8 | 9 | nwc->next = nwc; 10 | nwc->prev = nwc; 11 | 12 | return nwc; 13 | } 14 | 15 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd) 16 | { 17 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 18 | 19 | nwc->next = nwc; 20 | nwc->prev = nwc; 21 | nwc->pid = pid; 22 | nwc->fd = fd; 23 | 24 | return nwc; 25 | } 26 | 27 | void free_nwc_conn(struct nwc_connection *nwc) 28 | { 29 | if (nwc){ 30 | if (nwc->recv_buffer){ 31 | free(nwc->recv_buffer); 32 | nwc->recv_buffer = NULL; 33 | } 34 | 35 | if (nwc->fd != -1){ 36 | close(nwc->fd); 37 | nwc->fd = -1; 38 | } 39 | free(nwc); 40 | nwc = NULL; 41 | } 42 | } 43 | 44 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr) 45 | { 46 | struct nwc_connection *nwc = hdr->next; 47 | struct sockaddr_in *dstaddr = (struct sockaddr_in*)addr; 48 | 49 | for (; nwc != hdr;nwc = nwc->next){ 50 | if (nwc->addr.sin_port == dstaddr->sin_port 51 | && nwc->addr.sin_addr.s_addr == dstaddr->sin_addr.s_addr) 52 | return nwc; 53 | } 54 | 55 | return NULL; 56 | } 57 | 58 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc) 59 | { 60 | struct nwc_connection *prev = hdr->prev; 61 | struct nwc_connection *next = hdr; 62 | nwc->prev = prev; 63 | nwc->next = next; 64 | prev->next = nwc; 65 | next->prev = nwc; 66 | } 67 | 68 | void remove_nwc(struct nwc_connection *nwc) 69 | { 70 | struct nwc_connection *prev = nwc->prev; 71 | struct nwc_connection *next = nwc->next; 72 | 73 | prev->next = next; 74 | next->prev = prev; 75 | } 76 | void destroy_all_nwc(struct nwc_connection *hdr) 77 | { 78 | struct nwc_connection *nwc = hdr->next; 79 | for (; nwc != hdr;){ 80 | struct nwc_connection *next = nwc->next; 81 | free_nwc_conn(nwc); 82 | nwc = next; 83 | } 84 | } 85 | 86 | 87 | -------------------------------------------------------------------------------- /04-23_高级IO函数/nwc_connection.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_CONNECTION_H_ 2 | #define _NWC_CONNECTION_H_ 3 | 4 | #include 5 | #include 6 | #include // inet_addr() 7 | 8 | struct nwc_connection 9 | { 10 | struct nwc_connection *next; 11 | struct nwc_connection *prev; 12 | 13 | pid_t pid; 14 | int fd; 15 | int events; 16 | int echo_mode; 17 | struct sockaddr_in addr; 18 | char *recv_buffer; 19 | }; 20 | 21 | #define INIT_NWC(nwc)\ 22 | do { \ 23 | (nwc)->next = (nwc);\ 24 | (nwc)->prev = (nwc);\ 25 | (nwc)->pid = 0;\ 26 | (nwc)->fd = -1;\ 27 | (nwc)->events = 0;\ 28 | (nwc)->recv_buffer = NULL;\ 29 | }while(0); 30 | 31 | struct nwc_connection *alloc_nwc_conn_arg0(); 32 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd); 33 | void free_nwc_conn(struct nwc_connection *nwc); 34 | 35 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr); 36 | 37 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc); 38 | void remove_nwc(struct nwc_connection *nwc); 39 | void destroy_all_nwc(struct nwc_connection *hdr); 40 | 41 | 42 | #endif//_NWC_CONNECTION_H_ 43 | 44 | -------------------------------------------------------------------------------- /04-23_高级IO函数/nwchecker.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWCHECER_H_ 2 | #define _NWCHECER_H_ 3 | 4 | 5 | struct nwc_args 6 | { 7 | const char *ip; 8 | const char *localaddr; 9 | unsigned short port; 10 | int count; 11 | int no_close; 12 | int interval; // The unit is ms 13 | int sent_pkgs; // The sent packages of every slot. 14 | int message_size; // The send message size. 15 | int echo_mode; // 0:immediate, 1: random time, 2: no response, 3: server not recv 16 | int is_udp_connect; // The udp use connect() 17 | }; 18 | 19 | int nwc_client(struct nwc_args *na); 20 | int nwc_server(struct nwc_args *na); 21 | 22 | int nwc_udp_client(struct nwc_args *na); 23 | int nwc_udp_server(struct nwc_args *na); 24 | 25 | int unix_stream_client(struct nwc_args *na); 26 | int unix_stream_server(struct nwc_args *na); 27 | 28 | int unix_dgram_client(struct nwc_args *na); 29 | int unix_dgram_server(struct nwc_args *na); 30 | 31 | int nwc_server_process(struct nwc_args *na); 32 | 33 | char * alloc_buffer(int alloc_size); 34 | void free_buffer(char *buff); 35 | 36 | 37 | #endif//_NWCHECER_H_ 38 | 39 | -------------------------------------------------------------------------------- /04-23_高级IO函数/unix_dgram_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | int unix_dgram_client(struct nwc_args *na) 11 | { 12 | int rc = -1; 13 | struct sockaddr_un serveraddr, localaddr; 14 | 15 | int fd = socket(AF_LOCAL, SOCK_DGRAM, 0); 16 | if (fd == -1){ 17 | printf("Create unix dgram socket failed!errno(%d)\n", errno); 18 | return -1; 19 | } 20 | 21 | memset(&localaddr, 0, sizeof(localaddr)); 22 | localaddr.sun_family = AF_LOCAL; 23 | strncpy(localaddr.sun_path, na->localaddr, sizeof(localaddr.sun_path) - 1); 24 | 25 | unlink(localaddr.sun_path); 26 | 27 | rc = bind(fd, (struct sockaddr*)&localaddr, sizeof(localaddr)); 28 | if (rc == -1){ 29 | printf("Bind unix local dgram addr failed!errno(%d)\n", errno); 30 | close(fd); 31 | return -1; 32 | } 33 | 34 | memset(&serveraddr, 0, sizeof(serveraddr)); 35 | serveraddr.sun_family = AF_LOCAL; 36 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path) - 1); 37 | 38 | if (na->is_udp_connect){ 39 | rc = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 40 | if (rc == -1){ 41 | printf("Connect unix dgram server failed!errno(%d)\n", errno); 42 | close(fd); 43 | return -1; 44 | } 45 | } 46 | 47 | while(1){ 48 | if (na->is_udp_connect){ 49 | rc = sendto(fd, "ping", 4, 0, NULL , 0); 50 | }else{ 51 | rc = sendto(fd, "ping", 4, 0, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 52 | } 53 | if (rc == -1){ 54 | printf("Send ping failed!errno(%d)\n", errno); 55 | break; 56 | } 57 | 58 | printf("Send ping request!\n"); 59 | char buff[5] = {0}; 60 | 61 | struct sockaddr_un peeraddr; 62 | socklen_t peeraddrlen = sizeof(peeraddr); 63 | memset(&peeraddr, 0, sizeof(peeraddr)); 64 | 65 | if (na->is_udp_connect){ 66 | rc = recvfrom(fd, buff, 4, 0, NULL, 0); 67 | }else{ 68 | rc = recvfrom(fd, buff, 4, 0, (struct sockaddr*)&peeraddr, &peeraddrlen); 69 | } 70 | if (rc <= 0){ 71 | printf("Recv pong failed!errno(%d) rc(%d)\n", errno, rc); 72 | break; 73 | } 74 | 75 | printf("Recv (%s) response!\n", buff); 76 | } 77 | 78 | close(fd); 79 | 80 | return 0; 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /04-23_高级IO函数/unix_dgram_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | int unix_dgram_server(struct nwc_args *na) 11 | { 12 | int rc = -1; 13 | struct sockaddr_un serveraddr, peeraddr; 14 | socklen_t peeraddrlen; 15 | 16 | int fd = socket(AF_UNIX, SOCK_DGRAM, 0); 17 | if (fd == -1){ 18 | printf("Create unix dgram socket failed!errno(%d)\n", errno); 19 | return -1; 20 | } 21 | 22 | memset(&serveraddr, 0, sizeof(serveraddr)); 23 | 24 | serveraddr.sun_family = AF_UNIX; 25 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path)-1); 26 | unlink(serveraddr.sun_path); 27 | 28 | rc = bind(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 29 | if (rc == -1){ 30 | printf("Bind unix stream server failed!errno(%d)\n", errno); 31 | close(fd); 32 | return -1; 33 | } 34 | 35 | 36 | while (1){ 37 | char buff[5] = {0}; 38 | memset(&peeraddr, 0, sizeof(peeraddr)); 39 | peeraddrlen = sizeof(peeraddr); 40 | rc = recvfrom(fd, buff, 4, 0, (struct sockaddr*)&peeraddr, &peeraddrlen); 41 | if (rc <= 0){ 42 | printf("Recv ping failed!errno(%d) rc(%d)\n", errno, rc); 43 | continue; 44 | } 45 | 46 | printf("Recv (%s) request!\n", buff); 47 | rc = sendto(fd, "pong", 4, 0, (struct sockaddr*)&peeraddr, peeraddrlen); 48 | if (rc == -1){ 49 | printf("Send pong failed!errno(%d)\n", errno); 50 | continue; 51 | } 52 | 53 | printf("Send pong response!\n"); 54 | } 55 | 56 | close(fd); 57 | 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /04-23_高级IO函数/unix_stream_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "nwchecker.h" 10 | 11 | int unix_stream_client(struct nwc_args *na) 12 | { 13 | int rc = -1; 14 | struct sockaddr_un serveraddr; 15 | char *send_msg = NULL; 16 | size_t send_msg_len = 0; 17 | 18 | unsigned long total_send_size = 0; 19 | 20 | int fd = socket(AF_LOCAL, SOCK_STREAM, 0); 21 | if (fd == -1){ 22 | printf("Create unix sream socket failed!errno(%d)\n", errno); 23 | return -1; 24 | } 25 | 26 | memset(&serveraddr, 0, sizeof(serveraddr)); 27 | 28 | serveraddr.sun_family = AF_LOCAL; 29 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path) - 1); 30 | 31 | rc = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 32 | if (rc == -1){ 33 | printf("Connect unix stream server failed!errno(%d)\n", errno); 34 | close(fd); 35 | return -1; 36 | } 37 | 38 | useconds_t sleep_time = na->interval <= 0 ? 3000 : na->interval; 39 | int slot_send_count = na->sent_pkgs <= 0? 1: na->sent_pkgs; 40 | int cur_slot_sent = slot_send_count; 41 | int infinit = na->count <= 0 ? 1:0; 42 | int loop_count = na->count * slot_send_count; 43 | 44 | send_msg_len = na->message_size <= 0?5:na->message_size; 45 | send_msg = alloc_buffer(send_msg_len); 46 | 47 | struct timespec start, end; 48 | clock_gettime(CLOCK_MONOTONIC, &start); 49 | 50 | while(1){ 51 | rc = send(fd, send_msg, send_msg_len, 0); 52 | if (rc == -1){ 53 | printf("Send ping failed!errno(%d)\n", errno); 54 | break; 55 | } 56 | 57 | total_send_size += send_msg_len; 58 | 59 | if (send_msg_len <= 5){ 60 | printf("Send ping request!\n"); 61 | } 62 | char buff[5] = {0}; 63 | rc = recv(fd, buff, 4, 0); 64 | if (rc <= 0){ 65 | printf("Recv pong failed!errno(%d) rc(%d)\n", errno, rc); 66 | break; 67 | } 68 | 69 | if (send_msg_len <= 5){ 70 | printf("Recv (%s) response!\n", buff); 71 | } 72 | 73 | if (!infinit){ 74 | loop_count--; 75 | if (loop_count == 0){ 76 | break;// exit loop 77 | } 78 | } 79 | 80 | cur_slot_sent--; 81 | if (cur_slot_sent == 0){ 82 | usleep(sleep_time * 1000); 83 | cur_slot_sent = slot_send_count; 84 | } 85 | } 86 | 87 | clock_gettime(CLOCK_MONOTONIC, &end); 88 | unsigned long secs = (end.tv_sec - start.tv_sec) + (end.tv_nsec-end.tv_nsec)/1000000000; 89 | unsigned long bytes_per_sec = total_send_size; 90 | 91 | if (secs > 0){ 92 | bytes_per_sec = total_send_size/secs; 93 | } 94 | 95 | printf("Send totalsize(%lu) secs(%lu) bytes_per_sec(%lu)\n", 96 | total_send_size, 97 | secs, 98 | bytes_per_sec); 99 | 100 | close(fd); 101 | 102 | return 0; 103 | } 104 | 105 | 106 | -------------------------------------------------------------------------------- /04-24_UNIX异步IO机制/nwc_connection.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "nwc_connection.h" 4 | 5 | struct nwc_connection *alloc_nwc_conn_arg0() 6 | { 7 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 8 | 9 | nwc->next = nwc; 10 | nwc->prev = nwc; 11 | 12 | return nwc; 13 | } 14 | 15 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd) 16 | { 17 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 18 | 19 | nwc->next = nwc; 20 | nwc->prev = nwc; 21 | nwc->pid = pid; 22 | nwc->fd = fd; 23 | 24 | return nwc; 25 | } 26 | 27 | void free_nwc_conn(struct nwc_connection *nwc) 28 | { 29 | if (nwc){ 30 | if (nwc->recv_buffer){ 31 | free(nwc->recv_buffer); 32 | nwc->recv_buffer = NULL; 33 | } 34 | 35 | if (nwc->fd != -1){ 36 | close(nwc->fd); 37 | nwc->fd = -1; 38 | } 39 | free(nwc); 40 | nwc = NULL; 41 | } 42 | } 43 | 44 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr) 45 | { 46 | struct nwc_connection *nwc = hdr->next; 47 | struct sockaddr_in *dstaddr = (struct sockaddr_in*)addr; 48 | 49 | for (; nwc != hdr;nwc = nwc->next){ 50 | if (nwc->addr.sin_port == dstaddr->sin_port 51 | && nwc->addr.sin_addr.s_addr == dstaddr->sin_addr.s_addr) 52 | return nwc; 53 | } 54 | 55 | return NULL; 56 | } 57 | 58 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc) 59 | { 60 | struct nwc_connection *prev = hdr->prev; 61 | struct nwc_connection *next = hdr; 62 | nwc->prev = prev; 63 | nwc->next = next; 64 | prev->next = nwc; 65 | next->prev = nwc; 66 | } 67 | 68 | void remove_nwc(struct nwc_connection *nwc) 69 | { 70 | struct nwc_connection *prev = nwc->prev; 71 | struct nwc_connection *next = nwc->next; 72 | 73 | prev->next = next; 74 | next->prev = prev; 75 | } 76 | void destroy_all_nwc(struct nwc_connection *hdr) 77 | { 78 | struct nwc_connection *nwc = hdr->next; 79 | for (; nwc != hdr;){ 80 | struct nwc_connection *next = nwc->next; 81 | free_nwc_conn(nwc); 82 | nwc = next; 83 | } 84 | } 85 | 86 | 87 | -------------------------------------------------------------------------------- /04-24_UNIX异步IO机制/nwc_connection.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_CONNECTION_H_ 2 | #define _NWC_CONNECTION_H_ 3 | 4 | #include 5 | #include 6 | #include // inet_addr() 7 | 8 | struct nwc_connection 9 | { 10 | struct nwc_connection *next; 11 | struct nwc_connection *prev; 12 | 13 | pid_t pid; 14 | int fd; 15 | int events; 16 | int echo_mode; 17 | struct sockaddr_in addr; 18 | socklen_t addr_len; 19 | char *recv_buffer; 20 | }; 21 | 22 | #define INIT_NWC(nwc)\ 23 | do { \ 24 | (nwc)->next = (nwc);\ 25 | (nwc)->prev = (nwc);\ 26 | (nwc)->pid = 0;\ 27 | (nwc)->fd = -1;\ 28 | (nwc)->events = 0;\ 29 | (nwc)->recv_buffer = NULL;\ 30 | }while(0); 31 | 32 | struct nwc_connection *alloc_nwc_conn_arg0(); 33 | struct nwc_connection *alloc_nwc_conn(pid_t pid, int fd); 34 | void free_nwc_conn(struct nwc_connection *nwc); 35 | 36 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr); 37 | 38 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc); 39 | void remove_nwc(struct nwc_connection *nwc); 40 | void destroy_all_nwc(struct nwc_connection *hdr); 41 | 42 | 43 | #endif//_NWC_CONNECTION_H_ 44 | 45 | -------------------------------------------------------------------------------- /04-24_UNIX异步IO机制/nwchecker.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWCHECER_H_ 2 | #define _NWCHECER_H_ 3 | 4 | 5 | struct nwc_args 6 | { 7 | const char *ip; 8 | const char *localaddr; 9 | unsigned short port; 10 | int count; 11 | int no_close; 12 | int interval; // The unit is ms 13 | int sent_pkgs; // The sent packages of every slot. 14 | int message_size; // The send message size. 15 | int echo_mode; // 0:immediate, 1: random time, 2: no response, 3: server not recv 16 | int is_udp_connect; // The udp use connect() 17 | }; 18 | 19 | int nwc_client(struct nwc_args *na); 20 | int nwc_server(struct nwc_args *na); 21 | 22 | int nwc_udp_client(struct nwc_args *na); 23 | int nwc_udp_server(struct nwc_args *na); 24 | 25 | int unix_stream_client(struct nwc_args *na); 26 | int unix_stream_server(struct nwc_args *na); 27 | 28 | int unix_dgram_client(struct nwc_args *na); 29 | int unix_dgram_server(struct nwc_args *na); 30 | 31 | int nwc_server_process(struct nwc_args *na); 32 | int sigio_udp_server(struct nwc_args *na); 33 | 34 | char * alloc_buffer(int alloc_size); 35 | void free_buffer(char *buff); 36 | 37 | 38 | #endif//_NWCHECER_H_ 39 | 40 | -------------------------------------------------------------------------------- /04-24_UNIX异步IO机制/unix_dgram_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | int unix_dgram_client(struct nwc_args *na) 11 | { 12 | int rc = -1; 13 | struct sockaddr_un serveraddr, localaddr; 14 | 15 | int fd = socket(AF_LOCAL, SOCK_DGRAM, 0); 16 | if (fd == -1){ 17 | printf("Create unix dgram socket failed!errno(%d)\n", errno); 18 | return -1; 19 | } 20 | 21 | memset(&localaddr, 0, sizeof(localaddr)); 22 | localaddr.sun_family = AF_LOCAL; 23 | strncpy(localaddr.sun_path, na->localaddr, sizeof(localaddr.sun_path) - 1); 24 | 25 | unlink(localaddr.sun_path); 26 | 27 | rc = bind(fd, (struct sockaddr*)&localaddr, sizeof(localaddr)); 28 | if (rc == -1){ 29 | printf("Bind unix local dgram addr failed!errno(%d)\n", errno); 30 | close(fd); 31 | return -1; 32 | } 33 | 34 | memset(&serveraddr, 0, sizeof(serveraddr)); 35 | serveraddr.sun_family = AF_LOCAL; 36 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path) - 1); 37 | 38 | if (na->is_udp_connect){ 39 | rc = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 40 | if (rc == -1){ 41 | printf("Connect unix dgram server failed!errno(%d)\n", errno); 42 | close(fd); 43 | return -1; 44 | } 45 | } 46 | 47 | while(1){ 48 | if (na->is_udp_connect){ 49 | rc = sendto(fd, "ping", 4, 0, NULL , 0); 50 | }else{ 51 | rc = sendto(fd, "ping", 4, 0, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 52 | } 53 | if (rc == -1){ 54 | printf("Send ping failed!errno(%d)\n", errno); 55 | break; 56 | } 57 | 58 | printf("Send ping request!\n"); 59 | char buff[5] = {0}; 60 | 61 | struct sockaddr_un peeraddr; 62 | socklen_t peeraddrlen = sizeof(peeraddr); 63 | memset(&peeraddr, 0, sizeof(peeraddr)); 64 | 65 | if (na->is_udp_connect){ 66 | rc = recvfrom(fd, buff, 4, 0, NULL, 0); 67 | }else{ 68 | rc = recvfrom(fd, buff, 4, 0, (struct sockaddr*)&peeraddr, &peeraddrlen); 69 | } 70 | if (rc <= 0){ 71 | printf("Recv pong failed!errno(%d) rc(%d)\n", errno, rc); 72 | break; 73 | } 74 | 75 | printf("Recv (%s) response!\n", buff); 76 | } 77 | 78 | close(fd); 79 | 80 | return 0; 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /04-24_UNIX异步IO机制/unix_dgram_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "nwchecker.h" 9 | 10 | int unix_dgram_server(struct nwc_args *na) 11 | { 12 | int rc = -1; 13 | struct sockaddr_un serveraddr, peeraddr; 14 | socklen_t peeraddrlen; 15 | 16 | int fd = socket(AF_UNIX, SOCK_DGRAM, 0); 17 | if (fd == -1){ 18 | printf("Create unix dgram socket failed!errno(%d)\n", errno); 19 | return -1; 20 | } 21 | 22 | memset(&serveraddr, 0, sizeof(serveraddr)); 23 | 24 | serveraddr.sun_family = AF_UNIX; 25 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path)-1); 26 | unlink(serveraddr.sun_path); 27 | 28 | rc = bind(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 29 | if (rc == -1){ 30 | printf("Bind unix stream server failed!errno(%d)\n", errno); 31 | close(fd); 32 | return -1; 33 | } 34 | 35 | 36 | while (1){ 37 | char buff[5] = {0}; 38 | memset(&peeraddr, 0, sizeof(peeraddr)); 39 | peeraddrlen = sizeof(peeraddr); 40 | rc = recvfrom(fd, buff, 4, 0, (struct sockaddr*)&peeraddr, &peeraddrlen); 41 | if (rc <= 0){ 42 | printf("Recv ping failed!errno(%d) rc(%d)\n", errno, rc); 43 | continue; 44 | } 45 | 46 | printf("Recv (%s) request!\n", buff); 47 | rc = sendto(fd, "pong", 4, 0, (struct sockaddr*)&peeraddr, peeraddrlen); 48 | if (rc == -1){ 49 | printf("Send pong failed!errno(%d)\n", errno); 50 | continue; 51 | } 52 | 53 | printf("Send pong response!\n"); 54 | } 55 | 56 | close(fd); 57 | 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /04-24_UNIX异步IO机制/unix_stream_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "nwchecker.h" 10 | 11 | int unix_stream_client(struct nwc_args *na) 12 | { 13 | int rc = -1; 14 | struct sockaddr_un serveraddr; 15 | char *send_msg = NULL; 16 | size_t send_msg_len = 0; 17 | 18 | unsigned long total_send_size = 0; 19 | 20 | int fd = socket(AF_LOCAL, SOCK_STREAM, 0); 21 | if (fd == -1){ 22 | printf("Create unix sream socket failed!errno(%d)\n", errno); 23 | return -1; 24 | } 25 | 26 | memset(&serveraddr, 0, sizeof(serveraddr)); 27 | 28 | serveraddr.sun_family = AF_LOCAL; 29 | strncpy(serveraddr.sun_path, na->ip, sizeof(serveraddr.sun_path) - 1); 30 | 31 | rc = connect(fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); 32 | if (rc == -1){ 33 | printf("Connect unix stream server failed!errno(%d)\n", errno); 34 | close(fd); 35 | return -1; 36 | } 37 | 38 | useconds_t sleep_time = na->interval <= 0 ? 3000 : na->interval; 39 | int slot_send_count = na->sent_pkgs <= 0? 1: na->sent_pkgs; 40 | int cur_slot_sent = slot_send_count; 41 | int infinit = na->count <= 0 ? 1:0; 42 | int loop_count = na->count * slot_send_count; 43 | 44 | send_msg_len = na->message_size <= 0?5:na->message_size; 45 | send_msg = alloc_buffer(send_msg_len); 46 | 47 | struct timespec start, end; 48 | clock_gettime(CLOCK_MONOTONIC, &start); 49 | 50 | while(1){ 51 | rc = send(fd, send_msg, send_msg_len, 0); 52 | if (rc == -1){ 53 | printf("Send ping failed!errno(%d)\n", errno); 54 | break; 55 | } 56 | 57 | total_send_size += send_msg_len; 58 | 59 | if (send_msg_len <= 5){ 60 | printf("Send ping request!\n"); 61 | } 62 | char buff[5] = {0}; 63 | rc = recv(fd, buff, 4, 0); 64 | if (rc <= 0){ 65 | printf("Recv pong failed!errno(%d) rc(%d)\n", errno, rc); 66 | break; 67 | } 68 | 69 | if (send_msg_len <= 5){ 70 | printf("Recv (%s) response!\n", buff); 71 | } 72 | 73 | if (!infinit){ 74 | loop_count--; 75 | if (loop_count == 0){ 76 | break;// exit loop 77 | } 78 | } 79 | 80 | cur_slot_sent--; 81 | if (cur_slot_sent == 0){ 82 | usleep(sleep_time * 1000); 83 | cur_slot_sent = slot_send_count; 84 | } 85 | } 86 | 87 | clock_gettime(CLOCK_MONOTONIC, &end); 88 | unsigned long secs = (end.tv_sec - start.tv_sec) + (end.tv_nsec-end.tv_nsec)/1000000000; 89 | unsigned long bytes_per_sec = total_send_size; 90 | 91 | if (secs > 0){ 92 | bytes_per_sec = total_send_size/secs; 93 | } 94 | 95 | printf("Send totalsize(%lu) secs(%lu) bytes_per_sec(%lu)\n", 96 | total_send_size, 97 | secs, 98 | bytes_per_sec); 99 | 100 | close(fd); 101 | 102 | return 0; 103 | } 104 | 105 | 106 | -------------------------------------------------------------------------------- /04-25_Windows_IOCP机制/iocp_server/iocp_server.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.1062 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iocp_server", "iocp_server.vcxproj", "{3482352F-E949-4BD0-B121-59FD34EFA9B8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3482352F-E949-4BD0-B121-59FD34EFA9B8}.Debug|x64.ActiveCfg = Debug|x64 17 | {3482352F-E949-4BD0-B121-59FD34EFA9B8}.Debug|x64.Build.0 = Debug|x64 18 | {3482352F-E949-4BD0-B121-59FD34EFA9B8}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3482352F-E949-4BD0-B121-59FD34EFA9B8}.Debug|x86.Build.0 = Debug|Win32 20 | {3482352F-E949-4BD0-B121-59FD34EFA9B8}.Release|x64.ActiveCfg = Release|x64 21 | {3482352F-E949-4BD0-B121-59FD34EFA9B8}.Release|x64.Build.0 = Release|x64 22 | {3482352F-E949-4BD0-B121-59FD34EFA9B8}.Release|x86.ActiveCfg = Release|Win32 23 | {3482352F-E949-4BD0-B121-59FD34EFA9B8}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {D8CADEB6-B3AE-4625-BB70-BDE803E65337} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /04-25_Windows_IOCP机制/iocp_server/iocp_server.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /04-25_Windows_IOCP机制/iocp_server/iocp_server.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /04-25_Windows_IOCP机制/iocp_server/nwc_connection.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "nwc_connection.h" 4 | 5 | struct nwc_io_op * alloc_nwc_io_op(int op) 6 | { 7 | struct nwc_io_op *ioop = (struct nwc_io_op*)malloc(sizeof(struct nwc_io_op)); 8 | ioop->op = op; 9 | ioop->socket = INVALID_SOCKET; 10 | memset(&ioop->olapped, 0, sizeof(ioop->olapped)); 11 | return ioop; 12 | } 13 | void free_nwc_io_op(struct nwc_io_op *op) 14 | { 15 | if (op) { 16 | free(op); 17 | } 18 | } 19 | 20 | /////////////////// The nwc connection //////////////////////////////// 21 | struct nwc_connection *alloc_nwc_conn_arg0() 22 | { 23 | struct nwc_connection *nwc = (struct nwc_connection*)malloc(sizeof(struct nwc_connection)); 24 | 25 | nwc->next = nwc; 26 | nwc->prev = nwc; 27 | nwc->socket = INVALID_SOCKET; 28 | nwc->rbytes = 0; 29 | 30 | nwc->wsabuf.buf = nwc->recv_buff; 31 | nwc->wsabuf.len = RECV_BUFFER_LEN; 32 | 33 | return nwc; 34 | } 35 | 36 | 37 | void free_nwc_conn(struct nwc_connection *nwc) 38 | { 39 | if (nwc){ 40 | if (nwc->socket != INVALID_SOCKET) { 41 | closesocket(nwc->socket); 42 | nwc->socket = INVALID_SOCKET; 43 | } 44 | free(nwc); 45 | nwc = NULL; 46 | } 47 | } 48 | 49 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr) 50 | { 51 | struct nwc_connection *nwc = hdr->next; 52 | struct sockaddr_in *dstaddr = (struct sockaddr_in*)addr; 53 | 54 | for (; nwc != hdr;nwc = nwc->next){ 55 | if (nwc->addr.sin_port == dstaddr->sin_port 56 | && nwc->addr.sin_addr.s_addr == dstaddr->sin_addr.s_addr) 57 | return nwc; 58 | } 59 | 60 | return NULL; 61 | } 62 | 63 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc) 64 | { 65 | struct nwc_connection *prev = hdr->prev; 66 | struct nwc_connection *next = hdr; 67 | nwc->prev = prev; 68 | nwc->next = next; 69 | prev->next = nwc; 70 | next->prev = nwc; 71 | } 72 | 73 | void remove_nwc(struct nwc_connection *nwc) 74 | { 75 | struct nwc_connection *prev = nwc->prev; 76 | struct nwc_connection *next = nwc->next; 77 | 78 | prev->next = next; 79 | next->prev = prev; 80 | } 81 | void destroy_all_nwc(struct nwc_connection *hdr) 82 | { 83 | struct nwc_connection *nwc = hdr->next; 84 | for (; nwc != hdr;){ 85 | struct nwc_connection *next = nwc->next; 86 | free_nwc_conn(nwc); 87 | nwc = next; 88 | } 89 | } 90 | 91 | 92 | -------------------------------------------------------------------------------- /04-25_Windows_IOCP机制/iocp_server/nwc_connection.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_CONNECTION_H_ 2 | #define _NWC_CONNECTION_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | enum e_oper 14 | { 15 | OP_READ = 1, 16 | OP_ACCEPT, 17 | OP_WRITE 18 | }; 19 | 20 | struct nwc_io_op 21 | { 22 | OVERLAPPED olapped; 23 | int op; 24 | SOCKET socket; 25 | }; 26 | 27 | struct nwc_io_op * alloc_nwc_io_op(int op); 28 | void free_nwc_io_op(struct nwc_io_op *op); 29 | 30 | #define RECV_BUFFER_LEN 4096 31 | 32 | struct nwc_connection 33 | { 34 | struct nwc_connection *next; 35 | struct nwc_connection *prev; 36 | 37 | SOCKET socket; 38 | LPFN_ACCEPTEX lpfnAcceptEx; 39 | struct sockaddr_in addr; 40 | BYTE recv_buff[RECV_BUFFER_LEN]; 41 | DWORD rbytes; 42 | 43 | WSABUF wsabuf; 44 | int pending_ops; 45 | }; 46 | 47 | #define INIT_NWC(nwc)\ 48 | do { \ 49 | (nwc)->next = (nwc);\ 50 | (nwc)->prev = (nwc);\ 51 | (nwc)->socket = -1;\ 52 | (nwc)->lpfnAcceptEx = NULL;\ 53 | (nwc)->pending_ops = 0;\ 54 | }while(0); 55 | 56 | struct nwc_connection *alloc_nwc_conn_arg0(); 57 | void free_nwc_conn(struct nwc_connection *nwc); 58 | 59 | struct nwc_connection * get_nwc_connection(struct nwc_connection *hdr, struct sockaddr *addr); 60 | 61 | void add_nwc_tail(struct nwc_connection *hdr, struct nwc_connection *nwc); 62 | void remove_nwc(struct nwc_connection *nwc); 63 | void destroy_all_nwc(struct nwc_connection *hdr); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | #endif//_NWC_CONNECTION_H_ 69 | -------------------------------------------------------------------------------- /04-25_Windows_IOCP机制/iocp_server/nwchecker_server.c: -------------------------------------------------------------------------------- 1 | #ifndef WIN32_LEAN_AND_MEAN 2 | #define WIN32_LEAN_AND_MEAN 3 | #endif 4 | 5 | #include "nwcs_iocp.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | struct nwcs_iocp iocp; 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | unsigned short port = 800; 16 | int rc = 0; 17 | WSADATA wsaData = { 0 }; 18 | 19 | if (argc > 1) { 20 | port = atoi(argv[1]); 21 | } 22 | 23 | // Initialize winsock 24 | rc = WSAStartup(MAKEWORD(2, 2), &wsaData); 25 | if (rc != 0) { 26 | wprintf(L"WSAStartup failed: %d\n", rc); 27 | return -1;; 28 | } 29 | 30 | rc = nwcs_iocp_open(&iocp, port); 31 | if (rc != 0) { 32 | goto err; 33 | } 34 | 35 | nwcs_run_loop(&iocp); 36 | 37 | return 0; 38 | err: 39 | nwcs_iocp_close(&iocp); 40 | WSACleanup(); 41 | 42 | return -1; 43 | } -------------------------------------------------------------------------------- /04-25_Windows_IOCP机制/iocp_server/nwcs_iocp.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haska1025/imooc-sock-core-tech/b315bc1c3699fdc53feb6d86068be0f8642c7051/04-25_Windows_IOCP机制/iocp_server/nwcs_iocp.cpp -------------------------------------------------------------------------------- /04-25_Windows_IOCP机制/iocp_server/nwcs_iocp.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_IOCPS_H_ 2 | #define _NWC_IOCPS_H_ 3 | 4 | #include "nwc_connection.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | // An IOCP Instance 11 | struct nwcs_iocp 12 | { 13 | HANDLE completion_port; 14 | struct nwc_connection accept_conn; 15 | struct nwc_connection client_conn_hdr; 16 | struct nwc_connection delete_client_conn_hdr; 17 | BOOL is_exit; 18 | }; 19 | 20 | int nwcs_iocp_open(struct nwcs_iocp *iocp, unsigned short port); 21 | int nwcs_iocp_close(struct nwcs_iocp *iocp); 22 | int nwcs_accept_new_sock(struct nwcs_iocp *iocp, struct nwc_connection *nwc); 23 | int nwcs_accept_request(struct nwcs_iocp *iocp); 24 | void nwcs_run_loop(struct nwcs_iocp *iocp); 25 | void nwcs_iocp_process_message(struct nwcs_iocp *iocp, struct nwc_connection *nwc, struct nwc_io_op *ioop); 26 | 27 | int nwcs_read_request(struct nwc_connection *nwc); 28 | int nwcs_write_request(struct nwc_connection *nwc, const char *buff, unsigned int bulen); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif // !_NWC_IOCPS_H_ 35 | -------------------------------------------------------------------------------- /04-26_基于UDP组播的编程/mcast.h: -------------------------------------------------------------------------------- 1 | #ifndef _MCAST_H_ 2 | #define _MCAST_H_ 3 | 4 | #include 5 | 6 | int mcast_listen(int family, const char *port); 7 | int mcast_get_addr(const char *hostname, const char *service, struct sockaddr *addr); 8 | int mcast_join_group(int fd, struct sockaddr *mcast_addr, struct sockaddr *localaddr); 9 | int mcast_leave_group(int fd, struct sockaddr *mcast_addr, struct sockaddr *localaddr); 10 | int mcast_set_ttl(int fd, int family, int ttl); 11 | int mcast_set_loop(int fd, int family, int flag); 12 | 13 | int mcast_inet_ntop(struct sockaddr *addr, char ip[], int iplen); 14 | 15 | #endif//_MCAST_H_ 16 | 17 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/Makefile: -------------------------------------------------------------------------------- 1 | objs = nwc_connection.o \ 2 | nwc_looper.o \ 3 | nwc_epoll_looper.o \ 4 | nwc_main.o \ 5 | nwc_client.o \ 6 | nwc_server.o \ 7 | nwc_configuration.o \ 8 | nwc_tcp_handler.o \ 9 | nwc_udp_handler.o \ 10 | nwc.o \ 11 | nwc_sock.o \ 12 | nwc_qos_protocol.o 13 | 14 | DEBUG_FLAG = -g 15 | 16 | all:$(objs) 17 | $(CC) $(LDFLAGS) $^ -o nwc 18 | 19 | $(objs):%.o:%.c 20 | $(CC) $(DEBUG_FLAG) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ 21 | 22 | .PHONY: clean 23 | clean: 24 | @rm *.o nwc 25 | 26 | 27 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/list.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIST_H_ 2 | #define _LIST_H_ 3 | 4 | #include 5 | 6 | struct list_head 7 | { 8 | struct list_head *next; 9 | struct list_head *prev; 10 | }; 11 | 12 | static inline void INIT_LIST_HEAD(struct list_head *list) 13 | { 14 | list->next = list; 15 | list->prev = list; 16 | } 17 | 18 | static inline void __list_add(struct list_head *new, 19 | struct list_head *prev, 20 | struct list_head *next) 21 | { 22 | next->prev = new; 23 | new->next = next; 24 | new->prev = prev; 25 | prev->next = new; 26 | } 27 | 28 | 29 | static inline void list_add(struct list_head *new, struct list_head *head) 30 | { 31 | __list_add(new, head, head->next); 32 | } 33 | 34 | static inline void list_add_tail(struct list_head *new, struct list_head *head) 35 | { 36 | __list_add(new, head->prev, head); 37 | } 38 | 39 | static inline void __list_del(struct list_head * prev, struct list_head * next) 40 | { 41 | next->prev = prev; 42 | prev->next = next; 43 | } 44 | 45 | static inline void list_del(struct list_head *entry) 46 | { 47 | __list_del(entry->prev, entry->next); 48 | entry->next = NULL; 49 | entry->prev = NULL; 50 | } 51 | 52 | static inline int list_empty(const struct list_head *head) 53 | { 54 | return head->next == head; 55 | } 56 | 57 | #define container_of(ptr, type, member) \ 58 | (type *)(((char *)ptr)-offsetof(type, member)) 59 | 60 | #define list_entry(ptr, type, member) \ 61 | container_of(ptr, type, member) 62 | 63 | #define list_for_each(pos, head) \ 64 | for (pos = (head)->next; pos != (head); pos = pos->next) 65 | 66 | #define list_for_each_safe(pos, n, head) \ 67 | for (pos = (head)->next, n = pos->next; pos != (head); \ 68 | pos = n, n = pos->next) 69 | 70 | #endif//_LIST_H_ 71 | 72 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_H_ 2 | #define _NWC_H_ 3 | 4 | #include "nwc_types.h" 5 | 6 | struct nwc_io_handler; 7 | struct nwc_worker; 8 | 9 | nwc_handle_t nwc_looper_create(); 10 | void nwc_looper_destroy(nwc_handle_t looper); 11 | 12 | int nwc_looper_start(nwc_handle_t looper); 13 | nwc_handle_t nwc_looper_add_handler(nwc_handle_t looper, struct nwc_io_handler *handler); 14 | int nwc_looper_remove_handler(nwc_handle_t looper, nwc_handle_t handle); 15 | int nwc_looper_register_event(nwc_handle_t looper, nwc_handle_t handle, int events); 16 | int nwc_looper_cancel_event(nwc_handle_t looper, nwc_handle_t handle, int events); 17 | void nwc_looper_run(nwc_handle_t looper); 18 | int nwc_looper_stop(nwc_handle_t looper); 19 | nwc_handle_t nwc_looper_register_worker(nwc_handle_t looper, void *ud, int (*worker_do)(void *ud)); 20 | int nwc_looper_cancel_worker(nwc_handle_t looper, nwc_handle_t wk_handle); 21 | 22 | struct nwc_io_operation 23 | { 24 | void *userdata; 25 | 26 | struct nwc_io_operation *(*on_accept)(void *userdata, nwc_handle_t handle); 27 | void (*on_connect)(void *userdata); 28 | int (*on_recv)(void *userdata); 29 | int (*on_send)(void *userdata); 30 | }; 31 | 32 | void nwc_io_operation_init(struct nwc_io_operation *op); 33 | 34 | nwc_handle_t nwc_io_create(nwc_handle_t looper, struct nwc_io_operation *op, int prototype); 35 | 36 | int nwc_io_listen(nwc_handle_t looper, const char *ip, uint16_t port); 37 | int nwc_io_connect(nwc_handle_t looper, const char *ip, uint16_t port); 38 | int nwc_io_send(nwc_handle_t handle, uint8_t buff[], uint32_t bufflen); 39 | int nwc_io_sendto(nwc_handle_t handle, uint8_t buff[], uint32_t bufflen, struct sockaddr *toaddr, socklen_t toaddrlen); 40 | int nwc_io_recv(nwc_handle_t handle, uint8_t buff[], uint32_t bufflen); 41 | int nwc_io_recvfrom(nwc_handle_t handle, uint8_t buff[], uint32_t bufflen, struct sockaddr *fromaddr, socklen_t *fromaddrlen); 42 | int nwc_io_can_send(nwc_handle_t handle); 43 | int nwc_io_close(nwc_handle_t handle); 44 | nwc_handle_t nwc_io_get_looper(nwc_handle_t handle); 45 | 46 | 47 | #endif//_NWC_H_ 48 | 49 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "nwc.h" 6 | #include "nwc_connection.h" 7 | #include "nwc_configuration.h" 8 | 9 | static struct nwc_connection *conn = NULL; 10 | 11 | static int nwc_client_start(struct nwc_configuration *cfg, nwc_handle_t looper) 12 | { 13 | int rc = 0; 14 | 15 | conn = malloc(sizeof(struct nwc_connection)); 16 | nwc_connection_init(conn, cfg); 17 | 18 | conn->handle = nwc_io_create(looper, &conn->op, cfg->prototype); 19 | rc = nwc_io_connect(conn->handle, cfg->ip, cfg->port); 20 | printf("nwc_client_start connect to server ip(%s) port(%d) prototype(%d) rc(%d)\n", 21 | cfg->ip, cfg->port, cfg->prototype, rc); 22 | if (rc == 0){ 23 | nwc_connection_send(conn); 24 | }else if (rc == -EINPROGRESS){ 25 | ;//do nothing 26 | }else{ 27 | return rc; 28 | } 29 | 30 | return 0; 31 | } 32 | 33 | int nwc_client_main(struct nwc_configuration *cfg) 34 | { 35 | int rc = 0; 36 | 37 | if (!cfg->ip || !cfg->port) { 38 | printf("Please input server ip and port!\n"); 39 | return -1; 40 | } 41 | 42 | nwc_handle_t looper = nwc_looper_create(); 43 | 44 | rc = nwc_looper_start(looper); 45 | if (rc != 0) 46 | return rc; 47 | 48 | if (cfg->prototype == 0) 49 | cfg->prototype = NWC_PROTO_TCP; 50 | 51 | if (cfg->prototype == NWC_PROTO_TCP 52 | || cfg->prototype == NWC_PROTO_UDP){ 53 | rc = nwc_client_start(cfg, looper); 54 | if (rc != 0){ 55 | printf("Start client failed prototype(%d) rc(%d)\n", cfg->prototype, rc); 56 | return rc; 57 | } 58 | }else{ 59 | printf("Start client no prototype(%d)\n", cfg->prototype); 60 | return -1; 61 | } 62 | 63 | nwc_looper_run(looper); 64 | 65 | nwc_looper_stop(looper); 66 | nwc_looper_destroy(looper); 67 | 68 | return 0; 69 | } 70 | 71 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_configuration.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "nwc_types.h" 7 | #include "nwc_configuration.h" 8 | 9 | static void usage() 10 | { 11 | fprintf(stderr, "Usage: nwchecker [option]\n"); 12 | fprintf(stderr, " --help -h help information\n"); 13 | fprintf(stderr, " --client -c The client mode.\n"); 14 | fprintf(stderr, " --server -s The server mode.\n"); 15 | fprintf(stderr, " --port -p The server port.\n"); 16 | fprintf(stderr, " --address -a The server address.\n"); 17 | fprintf(stderr, " --count -o The total test time, unit is seconds.\n"); 18 | fprintf(stderr, " --bandwidth -b The user-defined bandwidth.\n"); 19 | fprintf(stderr, " --udp -u The UDP Socket.\n"); 20 | fprintf(stderr, " --tcp -t The TCP Socket.\n"); 21 | 22 | exit(0); 23 | } 24 | 25 | int nwc_configuration_parse(struct nwc_configuration *config, int argc, char *argv[]) 26 | { 27 | while (1) { 28 | int c = 0; 29 | int option_index = 0; 30 | static struct option long_options[] = { 31 | {"help", no_argument, 0, 'h'}, 32 | {"client", no_argument, 0, 'c'}, 33 | {"server", no_argument, 0, 's'}, 34 | {"port", required_argument, 0, 'p'}, 35 | {"address", required_argument, 0, 'a'}, 36 | {"count", required_argument, 0, 'o'}, 37 | {"bandwidth", required_argument,0, 'b'}, 38 | {"tcp", no_argument, 0, 't'}, 39 | {"udp", no_argument, 0, 'u'}, 40 | {0, 0, 0, 0 } 41 | }; 42 | 43 | c = getopt_long(argc, argv, "uthcsp:a:o:b:", long_options, &option_index); 44 | if (c == -1) 45 | break; 46 | 47 | switch (c) { 48 | case 'h': 49 | usage(); 50 | break; 51 | case 'c': 52 | config->mode = NWC_CLIENT; 53 | break; 54 | case 's': 55 | config->mode = NWC_SERVER; 56 | break; 57 | case 'p': 58 | config->port = atoi(optarg); 59 | break; 60 | case 'a': 61 | config->ip = optarg; 62 | break; 63 | case 'o': 64 | config->count_secs = atoi(optarg); 65 | break; 66 | case 'b': 67 | config->bandwidth = atoi(optarg); 68 | break; 69 | case 't': 70 | config->prototype = NWC_PROTO_TCP; 71 | break; 72 | case 'u': 73 | config->prototype = NWC_PROTO_UDP; 74 | break; 75 | default: 76 | usage(); 77 | } 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_configuration.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_CONFIGURATION_H_ 2 | #define _NWC_CONFIGURATION_H_ 3 | 4 | struct nwc_configuration 5 | { 6 | const char *ip; 7 | unsigned short port; 8 | int mode; // The app mode 9 | int prototype; // The protocol type 10 | int count_secs; // The test time, The unit is seconds. 11 | int bandwidth; // The user-defined bandwidth. 12 | }; 13 | 14 | int nwc_configuration_parse(struct nwc_configuration *config, int argc, char *argv[]); 15 | 16 | #endif//_NWC_CONFIGURATION_H_ 17 | 18 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_connection.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_CONNECTION_H_ 2 | #define _NWC_CONNECTION_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "list.h" 8 | #include "nwc.h" 9 | #include "nwc_configuration.h" 10 | #include "nwc_qos_protocol.h" 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | #define RECV_BUFFER_LEN 4096 17 | 18 | struct nwc_connection 19 | { 20 | struct nwc_io_operation op; 21 | struct list_head conn_entry; 22 | struct nwc_qos_protocol qos; 23 | nwc_handle_t handle; 24 | struct sockaddr_storage cliaddr; 25 | socklen_t cliaddrlen; 26 | uint8_t recv_buff[RECV_BUFFER_LEN]; 27 | uint32_t rbytes; 28 | struct nwc_configuration *cfg; 29 | 30 | nwc_handle_t stat_wk_handle; 31 | nwc_handle_t send_wk_handle; 32 | }; 33 | 34 | struct nwc_connection *alloc_nwc_conn_arg0(); 35 | void free_nwc_conn(struct nwc_connection *nwc); 36 | 37 | void nwc_connection_udp_accept(nwc_handle_t handle, struct nwc_configuration *cfg); 38 | 39 | void nwc_connection_init(struct nwc_connection *nwc, struct nwc_configuration *cfg); 40 | void nwc_connection_on_connect(void *userdata); 41 | int nwc_connection_on_recv(void *userdata); 42 | int nwc_connection_on_send(void *userdata); 43 | int nwc_connection_send(struct nwc_connection *nwc); 44 | void nwc_connection_close(struct nwc_connection *nwc); 45 | 46 | struct nwc_connection * get_nwc_connection(struct list_head *hdr, struct sockaddr *addr); 47 | void add_nwc_tail(struct list_head *hdr, struct nwc_connection *nwc); 48 | void remove_nwc(struct nwc_connection *nwc); 49 | void destroy_all_nwc(struct list_head *hdr); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | #endif//_NWC_CONNECTION_H_ 55 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_epoll_looper.h: -------------------------------------------------------------------------------- 1 | #ifndef _EPOLL_LOOPER_H_ 2 | #define _EPOLL_LOOPER_H_ 3 | 4 | #include "list.h" 5 | #include "nwc_types.h" 6 | #include "nwc_looper.h" 7 | 8 | struct nwc_io_handler; 9 | 10 | struct epoll_entry 11 | { 12 | int mask; 13 | int fd; 14 | struct nwc_io_handler *eh; 15 | struct list_head remove_entry; 16 | }; 17 | 18 | struct nwc_epoll_looper 19 | { 20 | struct nwc_looper parent; 21 | int epfd; 22 | int exit; 23 | 24 | int timeout_interval; 25 | struct list_head removed_epoll_entrys; 26 | }; 27 | 28 | int nwc_epoll_init(struct nwc_epoll_looper *looper); 29 | int nwc_epoll_start(struct nwc_looper *looper); 30 | nwc_handle_t nwc_epoll_add_handler(struct nwc_looper *looper, struct nwc_io_handler *handler); 31 | int nwc_epoll_remove_handler(struct nwc_looper *looper, nwc_handle_t handle); 32 | int nwc_epoll_register_event(struct nwc_looper *looper, nwc_handle_t handle, int events); 33 | int nwc_epoll_cancel_event(struct nwc_looper *looper, nwc_handle_t handle, int events); 34 | void nwc_epoll_run(struct nwc_looper *looper); 35 | int nwc_epoll_stop(struct nwc_looper *looper); 36 | 37 | 38 | #define epoll_looper(looper)\ 39 | (struct nwc_epoll_looper *)(looper) 40 | 41 | #endif//_EPOLL_LOOPER_H_ 42 | 43 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_io_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_IO_HANDLER_H_ 2 | #define _NWC_IO_HANDLER_H_ 3 | 4 | #include "nwc_types.h" 5 | #include "nwc.h" 6 | 7 | #define EM_READ 1 8 | #define EM_WRITE 2 9 | #define EM_ALL (EM_READ | EM_WRITE) 10 | 11 | // The base io handler 12 | struct nwc_io_handler 13 | { 14 | void (*handle_input)(struct nwc_io_handler *handler); 15 | void (*handle_output)(struct nwc_io_handler *handler); 16 | 17 | int (*listen)(struct nwc_io_handler *handler, const char *ip, uint16_t port); 18 | int (*connect)(struct nwc_io_handler *handler, const char *hostname, uint16_t port); 19 | int (*accept)(struct nwc_io_handler *handler, int fd); 20 | int (*send)(struct nwc_io_handler *handler, const uint8_t buffer[], uint32_t buflen); 21 | int (*recv)(struct nwc_io_handler *handler, uint8_t buffer[], uint32_t buflen); 22 | int (*sendto)(struct nwc_io_handler *handler, const uint8_t buffer[], uint32_t buflen, struct sockaddr *toaddr, socklen_t toaddrlen); 23 | int (*recvfrom)(struct nwc_io_handler *handler, uint8_t buffer[], uint32_t buflen, struct sockaddr *fromaddr, socklen_t *fromaddrlen); 24 | int (*close)(struct nwc_io_handler *handler); 25 | 26 | nwc_handle_t looper; 27 | int fd; // socket file description 28 | nwc_handle_t h_handle; // The handle for io_handler 29 | struct nwc_io_operation *ioop; 30 | int can_send; 31 | }; 32 | 33 | static inline void nwc_io_handler_init(struct nwc_io_handler *h) 34 | { 35 | h->handle_input = NULL; 36 | h->handle_output = NULL; 37 | 38 | h->listen = NULL; 39 | h->connect = NULL; 40 | h->send = NULL; 41 | h->sendto = NULL; 42 | h->recv = NULL; 43 | h->recvfrom = NULL; 44 | h->close = NULL; 45 | 46 | h->looper = INVALID_HANDLE; 47 | h->fd = -1; 48 | h->h_handle = INVALID_HANDLE; 49 | h->ioop = NULL; 50 | h->can_send = 1; 51 | } 52 | 53 | #endif//_NWC_IO_HANDLER_H_ 54 | 55 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_looper.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "nwc_looper.h" 3 | 4 | static nwc_handle_t nwc_looper_register_worker(struct nwc_looper *looper, void *ud, int (*worker_do)(void *ud)) 5 | { 6 | struct nwc_worker *worker = malloc(sizeof(struct nwc_worker)); 7 | worker->worker_do = worker_do; 8 | worker->userdata = ud; 9 | 10 | list_add_tail(&worker->worker_entry, &looper->worker_hdr); 11 | 12 | return (nwc_handle_t)worker; 13 | } 14 | static int nwc_looper_cancel_worker(struct nwc_looper *looper, nwc_handle_t wk_handle) 15 | { 16 | struct nwc_worker *wk = (struct nwc_worker*)wk_handle; 17 | list_del(&wk->worker_entry); 18 | 19 | wk->userdata = NULL; 20 | wk->worker_do = NULL; 21 | list_add_tail(&wk->worker_entry, &looper->removed_worker_hdr); 22 | 23 | return 0; 24 | } 25 | 26 | void nwc_looper_init(struct nwc_looper *looper) 27 | { 28 | INIT_LIST_HEAD(&looper->worker_hdr); 29 | INIT_LIST_HEAD(&looper->removed_worker_hdr); 30 | 31 | looper->register_worker = nwc_looper_register_worker; 32 | looper->cancel_worker = nwc_looper_cancel_worker; 33 | } 34 | 35 | void nwc_looper_dispatch_worker(struct nwc_looper *looper) 36 | { 37 | struct list_head *pos, *n; 38 | 39 | list_for_each_safe(pos, n, &looper->worker_hdr){ 40 | struct nwc_worker *entry = list_entry(pos, struct nwc_worker, worker_entry); 41 | if (entry->worker_do){ 42 | entry->worker_do(entry->userdata); 43 | }else{ 44 | list_del(pos); 45 | free(entry); 46 | entry = NULL; 47 | } 48 | } 49 | } 50 | void nwc_looper_delete_removed_worker(struct nwc_looper *looper) 51 | { 52 | struct list_head *pos, *n; 53 | 54 | list_for_each_safe(pos, n, &looper->removed_worker_hdr){ 55 | struct nwc_worker *entry = list_entry(pos, struct nwc_worker, worker_entry); 56 | list_del(pos); 57 | free(entry); 58 | entry = NULL; 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_looper.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_LOOPER_BASE_H_ 2 | #define _NWC_LOOPER_BASE_H_ 3 | 4 | #include "nwc_types.h" 5 | #include "list.h" 6 | 7 | struct nwc_io_handler; 8 | 9 | struct nwc_looper 10 | { 11 | int (*start)(struct nwc_looper *looper); 12 | int (*stop)(struct nwc_looper *looper); 13 | nwc_handle_t (*add_handler)(struct nwc_looper *looper, struct nwc_io_handler *handler); 14 | int (*remove_handler)(struct nwc_looper *looper,nwc_handle_t handle); 15 | int (*register_event)(struct nwc_looper *looper,nwc_handle_t handle, int events); 16 | int (*cancel_event)(struct nwc_looper *looper,nwc_handle_t handle, int events); 17 | void (*run)(struct nwc_looper *looper); 18 | nwc_handle_t (*register_worker)(struct nwc_looper *looper, void *ud, int (*worker_do)(void *ud)); 19 | int (*cancel_worker)(struct nwc_looper *looper, nwc_handle_t wk_handle); 20 | 21 | struct list_head worker_hdr; 22 | struct list_head removed_worker_hdr; 23 | }; 24 | 25 | void nwc_looper_init(struct nwc_looper *looper); 26 | 27 | struct nwc_worker 28 | { 29 | void *userdata; 30 | int (*worker_do)(void *userdata); 31 | struct list_head worker_entry; 32 | }; 33 | 34 | void nwc_looper_dispatch_worker(struct nwc_looper *looper); 35 | void nwc_looper_delete_removed_worker(struct nwc_looper *looper); 36 | 37 | 38 | #endif//_NWC_LOOPER_BASE_H_ 39 | 40 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "nwc_configuration.h" 6 | #include "nwc.h" 7 | 8 | int nwc_client_main(struct nwc_configuration *cfg); 9 | int nwc_server_main(struct nwc_configuration *cfg); 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | int rc = 0; 14 | struct nwc_configuration cfg; 15 | 16 | if (argc < 2){ 17 | printf("You must select the app mode!\n"); 18 | return -1; 19 | } 20 | 21 | memset(&cfg, 0, sizeof(struct nwc_configuration)); 22 | 23 | rc = nwc_configuration_parse(&cfg, argc, argv); 24 | if (rc != 0){ 25 | printf("Parse configure failed!\n"); 26 | return -1; 27 | } 28 | 29 | /* 30 | * if (daemon(0, 0) == -1){ 31 | * printf("Create daemon failed.errno(%d)\n", errno); 32 | * exit(-1); 33 | * } 34 | */ 35 | 36 | signal(SIGPIPE, SIG_IGN); 37 | 38 | if (cfg.mode == NWC_CLIENT){ 39 | nwc_client_main(&cfg); 40 | }else if(cfg.mode == NWC_SERVER){ 41 | rc = nwc_server_main(&cfg); 42 | if (rc != 0){ 43 | printf("Start server failed! error(%d)\n", rc); 44 | return rc; 45 | } 46 | } 47 | 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_qos_protocol.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_QOS_PROTOCOL_H_ 2 | #define _NWC_QOS_PROTOCOL_H_ 3 | 4 | #include 5 | 6 | #include "list.h" 7 | 8 | struct nwc_qos_hdr 9 | { 10 | uint32_t timestamp; // Send timestamp 11 | uint32_t ack_timestamp; // Ack timestamp 12 | uint32_t recv_delay; // The delay for receiver process message 13 | uint32_t length; // The length of the payload 14 | uint8_t data[0]; // dummy field 15 | }; 16 | 17 | #define LOSS_FLAG 1 18 | #define INORDER_FLAG 2 19 | 20 | // The package wrapper for saving 21 | struct nwc_package_entry 22 | { 23 | struct nwc_qos_hdr *message; 24 | int flag; 25 | struct list_head package_entry; 26 | }; 27 | 28 | struct nwc_qos_protocol 29 | { 30 | double rtt; 31 | uint32_t loss_packages_per_secs; 32 | uint32_t sent_packages_per_secs; 33 | double jitter; 34 | uint32_t recv_timestamp; 35 | uint32_t recv_time; 36 | uint32_t sent_bytes; 37 | uint32_t send_bandwidth; 38 | uint32_t last_stat_ts; 39 | int stat_interval; 40 | 41 | struct list_head sent_queue; 42 | }; 43 | 44 | int nwc_qos_init(struct nwc_qos_protocol *qos); 45 | struct nwc_qos_hdr * nwc_qos_create_package(struct nwc_qos_protocol *qos, uint32_t packagelen); 46 | struct nwc_qos_hdr * nwc_qos_create_ack_package(struct nwc_qos_protocol *qos, uint32_t ack_ts); 47 | int nwc_qos_process_package(struct nwc_qos_protocol *qos, struct nwc_qos_hdr *pkg, uint32_t recv_ts); 48 | int nwc_qos_stat(struct nwc_qos_protocol *qos); 49 | 50 | uint32_t nwc_qos_milisecs(); 51 | 52 | #endif//_NWC_QOS_PROTOCOL_H_ 53 | 54 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "nwc.h" 5 | #include "nwc_connection.h" 6 | 7 | #define DEFAULT_PORT 9820 8 | 9 | struct nwc_io_operation *listen_op = NULL; 10 | nwc_handle_t listen_handle = INVALID_HANDLE; 11 | struct list_head conn_hdr; 12 | 13 | static struct nwc_io_operation *nwc_server_accept(void *userdata, nwc_handle_t handle) 14 | { 15 | struct nwc_configuration *cfg = (struct nwc_configuration*)userdata; 16 | 17 | if(cfg->prototype == NWC_PROTO_UDP){ 18 | nwc_connection_udp_accept(handle, cfg); 19 | return NULL; 20 | }else{ 21 | struct nwc_connection *conn = malloc(sizeof(struct nwc_connection)); 22 | 23 | nwc_connection_init(conn, cfg); 24 | conn->handle = handle; 25 | 26 | // Save the connection to connection list 27 | list_add_tail(&conn->conn_entry, &conn_hdr); 28 | 29 | return (struct nwc_io_operation*)conn; 30 | } 31 | } 32 | 33 | static int nwc_server_start(struct nwc_configuration *cfg, nwc_handle_t looper) 34 | { 35 | INIT_LIST_HEAD(&conn_hdr); 36 | 37 | listen_op = malloc(sizeof(struct nwc_io_operation)); 38 | 39 | nwc_io_operation_init(listen_op); 40 | // Let the configuration as the userdata 41 | listen_op->userdata = cfg; 42 | listen_op->on_accept = nwc_server_accept; 43 | 44 | listen_handle = nwc_io_create(looper, listen_op, cfg->prototype); 45 | 46 | return nwc_io_listen(listen_handle, cfg->ip, cfg->port); 47 | } 48 | 49 | static int nwc_server_stop() 50 | { 51 | nwc_io_close(listen_handle); 52 | free(listen_op); 53 | listen_op = NULL; 54 | 55 | return 0; 56 | } 57 | 58 | int nwc_server_main(struct nwc_configuration *cfg) 59 | { 60 | int rc = 0; 61 | nwc_handle_t looper = nwc_looper_create(); 62 | 63 | rc = nwc_looper_start(looper); 64 | if (rc != 0) 65 | return rc; 66 | 67 | if (cfg->port == 0){ 68 | cfg->port = DEFAULT_PORT; 69 | } 70 | if (cfg->prototype == 0){ 71 | cfg->prototype = NWC_PROTO_TCP; 72 | } 73 | 74 | if (cfg->prototype == NWC_PROTO_TCP 75 | || cfg->prototype == NWC_PROTO_UDP){ 76 | rc = nwc_server_start(cfg, looper); 77 | if (rc != 0) 78 | return rc; 79 | }else{ 80 | printf("Start server no prototype(%d)\n", cfg->prototype); 81 | return -1; 82 | } 83 | 84 | nwc_looper_run(looper); 85 | 86 | nwc_server_stop(); 87 | 88 | return 0; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_sock.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_SOCK_H_ 2 | #define _NWC_SOCK_H_ 3 | 4 | #include 5 | 6 | int nwc_sock_create(int family, int socktype, int protocol, int nonblock, int reuseaddr); 7 | int nwc_sock_listen(int family, int socktype, const char *host, uint16_t port); 8 | int nwc_sock_connect(int family, int socktype, const char *peerhost, uint8_t peerport, int *fd); 9 | 10 | #endif//_NWC_SOCK_H_ 11 | 12 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_tcp_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_TCP_HANDLER_H_ 2 | #define _NWC_TCP_HANDLER_H_ 3 | 4 | #include "nwc_io_handler.h" 5 | 6 | enum NWC_TCP_STATE 7 | { 8 | NTS_CLOSED = 1, 9 | NTS_LISTEN, 10 | NTS_CONNECTING, 11 | NTS_ESTABLISHED 12 | }; 13 | 14 | struct nwc_tcp_handler 15 | { 16 | struct nwc_io_handler parent; 17 | int state; 18 | }; 19 | 20 | int nwc_tcp_handler_init(struct nwc_tcp_handler *handler); 21 | int nwc_tcp_handler_accept(struct nwc_tcp_handler *handler, int fd); 22 | 23 | int nwc_tcp_handler_listen(struct nwc_io_handler *handler, const char *ip, uint16_t port); 24 | int nwc_tcp_handler_connect(struct nwc_io_handler *handler, const char *hostname, uint16_t port); 25 | int nwc_tcp_handler_send(struct nwc_io_handler *handler, const uint8_t buffer[], uint32_t buflen); 26 | int nwc_tcp_handler_recv(struct nwc_io_handler *handler, uint8_t buffer[], uint32_t buflen); 27 | int nwc_tcp_handler_close(struct nwc_io_handler *handler); 28 | void nwc_tcp_handle_input(struct nwc_io_handler *handler); 29 | void nwc_tcp_handle_output(struct nwc_io_handler *handler); 30 | 31 | #define tcp_handler(io_handler) \ 32 | (struct nwc_tcp_handler*)(io_handler) 33 | 34 | #endif//_NWC_TCP_HANDLER_H_ 35 | 36 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_types.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_TYPES_H_ 2 | #define _NWC_TYPES_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define NWC_CLIENT 1 9 | #define NWC_SERVER 2 10 | 11 | #define NWC_PROTO_TCP 1 12 | #define NWC_PROTO_UDP 2 13 | 14 | 15 | typedef intptr_t nwc_handle_t; 16 | #define INVALID_HANDLE (-1) 17 | 18 | #define SCHEDULE_TIMER 50 19 | 20 | #endif//_NWC_TYPES_H_ 21 | 22 | -------------------------------------------------------------------------------- /04-30_nwchecker_refactor/nwc_udp_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef _NWC_UDP_HANDLER_H_ 2 | #define _NWC_UDP_HANDLER_H_ 3 | 4 | #include "nwc_io_handler.h" 5 | 6 | struct nwc_udp_handler 7 | { 8 | struct nwc_io_handler parent; 9 | int type; 10 | }; 11 | 12 | int nwc_udp_handler_init(struct nwc_udp_handler *handler); 13 | 14 | int nwc_udp_handler_listen(struct nwc_io_handler *handler, const char *ip, uint16_t port); 15 | int nwc_udp_handler_connect(struct nwc_io_handler *handler, const char *hostname, uint16_t port); 16 | int nwc_udp_handler_sendto(struct nwc_io_handler *handler, const uint8_t buffer[], uint32_t buflen, struct sockaddr *toaddr, socklen_t toaddrlen); 17 | int nwc_udp_handler_recvfrom(struct nwc_io_handler *handler, uint8_t buffer[], uint32_t buflen, struct sockaddr *fromaddr, socklen_t *fromaddrlen); 18 | int nwc_udp_handler_send(struct nwc_io_handler *handler, const uint8_t buffer[], uint32_t buflen); 19 | int nwc_udp_handler_recv(struct nwc_io_handler *handler, uint8_t buffer[], uint32_t buflen); 20 | int nwc_udp_handler_close(struct nwc_io_handler *handler); 21 | void nwc_udp_handle_input(struct nwc_io_handler *handler); 22 | void nwc_udp_handle_output(struct nwc_io_handler *handler); 23 | 24 | #define udp_handler(io_handler) \ 25 | (struct nwc_udp_handler*)(io_handler) 26 | 27 | 28 | #endif//_NWC_UDP_HANDLER_H_ 29 | 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 介绍 2 | 3 | 慕课网专栏《 零基础学透网络编程》的配套代码 4 | -------------------------------------------------------------------------------- /java_netprogramming/.idea/dictionaries/Administrator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /java_netprogramming/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /java_netprogramming/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /java_netprogramming/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /java_netprogramming/java_netprogramming.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/asynchronous/AsyncClient.java: -------------------------------------------------------------------------------- 1 | package com.haska.asynchronous; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.AsynchronousSocketChannel; 6 | import java.util.concurrent.Future; 7 | 8 | public class AsyncClient { 9 | private static final int PORT =56002; 10 | public static void main(String[] args) { 11 | try (AsynchronousSocketChannel client = AsynchronousSocketChannel.open()) { 12 | Future result = client.connect(new InetSocketAddress("127.0.0.1", PORT)); 13 | System.out.println("Async connect the server"); 14 | result.get(); 15 | 16 | String reqMessage = "Hello server!"; 17 | ByteBuffer reqBuffer = ByteBuffer.wrap(reqMessage.getBytes()); 18 | Future writeResult = client.write(reqBuffer); 19 | System.out.println("Async send to server:" + reqMessage); 20 | writeResult.get(); 21 | 22 | ByteBuffer inBuffer = ByteBuffer.allocate(128); 23 | Future readResult = client.read(inBuffer); 24 | readResult.get(); 25 | System.out.println("Async recv from server:" + new String(inBuffer.array()).trim()); 26 | } catch (Exception e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/asynchronous/AsyncClientFuture.java: -------------------------------------------------------------------------------- 1 | package com.haska.asynchronous; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.AsynchronousSocketChannel; 6 | import java.util.concurrent.Future; 7 | 8 | public class AsyncClientFuture { 9 | private static final int PORT =56002; 10 | private static int COUNT = 10; 11 | public static void main(String[] args) { 12 | try (AsynchronousSocketChannel client = AsynchronousSocketChannel.open()) { 13 | Future result = client.connect(new InetSocketAddress("127.0.0.1", PORT)); 14 | System.out.println("Async connect the server"); 15 | result.get(); 16 | 17 | int i = 0; 18 | while(i++ < COUNT) { 19 | String reqMessage = "Hello server!"; 20 | ByteBuffer reqBuffer = ByteBuffer.wrap(reqMessage.getBytes()); 21 | Future writeResult = client.write(reqBuffer); 22 | System.out.println("Async send to server:" + reqMessage); 23 | writeResult.get(); 24 | 25 | ByteBuffer inBuffer = ByteBuffer.allocate(128); 26 | Future readResult = client.read(inBuffer); 27 | readResult.get(); 28 | System.out.println("Async recv from server:" + new String(inBuffer.array()).trim()); 29 | Thread.sleep(1000); 30 | } 31 | } catch (Exception e) { 32 | e.printStackTrace(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/asynchronous/AsyncServer.java: -------------------------------------------------------------------------------- 1 | package com.haska.asynchronous; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.nio.ByteBuffer; 6 | import java.nio.channels.AsynchronousServerSocketChannel; 7 | import java.nio.channels.AsynchronousSocketChannel; 8 | import java.util.concurrent.Future; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | public class AsyncServer { 12 | private static final int PORT =56002; 13 | 14 | public static void main(String[] args) { 15 | try (AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open()){ 16 | server.bind(new InetSocketAddress("127.0.0.1", PORT)); 17 | 18 | Future acceptFuture = server.accept(); 19 | AsynchronousSocketChannel client = acceptFuture.get(10, TimeUnit.SECONDS); 20 | 21 | if (client != null && client.isOpen()){ 22 | ByteBuffer inBuffer = ByteBuffer.allocate(128); 23 | Future readResult = client.read(inBuffer); 24 | System.out.println("Do something"); 25 | readResult.get(); 26 | 27 | inBuffer.flip(); 28 | Future writeResult = client.write(inBuffer); 29 | writeResult.get(); 30 | } 31 | 32 | client.close(); 33 | } catch (Exception e) { 34 | e.printStackTrace(); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/buffer/ByteBufferDemo.java: -------------------------------------------------------------------------------- 1 | package com.haska.buffer; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.IntBuffer; 5 | import java.nio.LongBuffer; 6 | 7 | public class ByteBufferDemo { 8 | public static void test_bytebuffer(){ 9 | ByteBuffer newBuffer = ByteBuffer.allocate(1024); 10 | System.out.println("new ByteBuffer capacity=" + newBuffer.capacity() 11 | + " position=" + newBuffer.position() + " limit=" + newBuffer.limit()); 12 | 13 | byte[] tmpByteArray = new byte[512]; 14 | ByteBuffer wrapBuffer = ByteBuffer.wrap(tmpByteArray); 15 | System.out.println("new ByteBuffer capacity=" + wrapBuffer.capacity() 16 | + " position=" + wrapBuffer.position() + " limit=" + wrapBuffer.limit()); 17 | 18 | tmpByteArray[0] = (byte)0x11; 19 | tmpByteArray[1] = (byte)0x22; 20 | newBuffer.put((byte)0xAA); 21 | newBuffer.put((byte)0xBB); 22 | newBuffer.put(tmpByteArray, 0, 2); 23 | System.out.println("new ByteBuffer capacity=" + newBuffer.capacity() 24 | + " position=" + newBuffer.position() + " limit=" + newBuffer.limit()); 25 | 26 | newBuffer.flip(); 27 | System.out.println("new ByteBuffer capacity=" + newBuffer.capacity() 28 | + " position=" + newBuffer.position() + " limit=" + newBuffer.limit()); 29 | 30 | newBuffer.get(); 31 | newBuffer.get(tmpByteArray, 0, 2); 32 | System.out.println("new ByteBuffer capacity=" + newBuffer.capacity() 33 | + " position=" + newBuffer.position() + " limit=" + newBuffer.limit()); 34 | 35 | newBuffer.rewind(); 36 | newBuffer.compact(); 37 | } 38 | public static void main(String[] args) { 39 | test_bytebuffer(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/multithreadserver/TCPClientMultiThread.java: -------------------------------------------------------------------------------- 1 | package com.haska.multithreadserver; 2 | 3 | import java.io.*; 4 | import java.net.InetSocketAddress; 5 | import java.net.Socket; 6 | import java.net.SocketAddress; 7 | 8 | public class TCPClientMultiThread { 9 | // 服务器监听的端口号 10 | private static final int PORT = 56002; 11 | // 连接超时时间 12 | private static final int TIMEOUT = 15000; 13 | // 客户端执行次数 14 | private static final int TEST_TIMES = 10; 15 | 16 | public static void main(String[] args) { 17 | Socket client = null; 18 | try { 19 | // 测试次数 20 | int testCount = 0; 21 | // 调用无参构造方法 22 | client = new Socket(); 23 | // 构造服务器地址结构 24 | SocketAddress serverAddr = new InetSocketAddress("192.168.0.101", PORT); 25 | // 连接服务器,超时时间是 15 毫秒 26 | client.connect(serverAddr, TIMEOUT); 27 | 28 | System.out.println("Client start:" + client.getLocalSocketAddress().toString()); 29 | while (true) { 30 | // 向服务器发送数据 31 | DataOutputStream out = new DataOutputStream( 32 | new BufferedOutputStream(client.getOutputStream())); 33 | String req = "Hello Server!"; 34 | out.writeInt(req.getBytes().length); 35 | out.write(req.getBytes()); 36 | // 不能忘记 flush 方法的调用 37 | out.flush(); 38 | System.out.println("Send to server:" + req); 39 | 40 | // 接收服务器的数据 41 | DataInputStream in = new DataInputStream( 42 | new BufferedInputStream(client.getInputStream())); 43 | 44 | int msgLen = in.readInt(); 45 | byte[] inMessage = new byte[msgLen]; 46 | in.read(inMessage); 47 | System.out.println("Recv from server:" + new String(inMessage)); 48 | 49 | // 如果执行次数已经达到上限,结束测试。 50 | if (++testCount >= TEST_TIMES) { 51 | break; 52 | } 53 | 54 | // 等待 1 秒然后再执行 55 | try { 56 | Thread.sleep(1000); 57 | } catch (InterruptedException e) { 58 | e.printStackTrace(); 59 | } 60 | } 61 | } catch (IOException e) { 62 | e.printStackTrace(); 63 | } finally { 64 | if (client != null){ 65 | try { 66 | client.close(); 67 | } catch (IOException e) { 68 | e.printStackTrace(); 69 | } 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/multithreadserver/TCPServerPerThread.java: -------------------------------------------------------------------------------- 1 | package com.haska.multithreadserver; 2 | 3 | import java.io.*; 4 | import java.net.ServerSocket; 5 | import java.net.Socket; 6 | 7 | public class TCPServerPerThread implements Runnable{ 8 | private static final int PORT =56002; 9 | 10 | private Socket sock = null; 11 | 12 | TCPServerPerThread(Socket sock){ 13 | this.sock = sock; 14 | } 15 | 16 | @Override 17 | public void run() { 18 | // 读取客户端数据 19 | try { 20 | while (true){ 21 | // 读取客户端数据 22 | DataInputStream in = new DataInputStream( 23 | new BufferedInputStream(sock.getInputStream())); 24 | int msgLen = in.readInt(); 25 | byte[] inMessage = new byte[msgLen]; 26 | in.read(inMessage); 27 | System.out.println("Recv from client:" + new String(inMessage) + "length:" + msgLen); 28 | 29 | // 向客户端发送数据 30 | String rsp = "Hello Client!\n"; 31 | DataOutputStream out = new DataOutputStream( 32 | new BufferedOutputStream(sock.getOutputStream())); 33 | out.writeInt(rsp.getBytes().length); 34 | out.write(rsp.getBytes()); 35 | out.flush(); 36 | System.out.println("Send to client:" + rsp + " length:" + rsp.getBytes().length); 37 | } 38 | } catch (IOException e) { 39 | e.printStackTrace(); 40 | } finally { 41 | if (sock != null){ 42 | try { 43 | sock.close(); 44 | } catch (IOException e) { 45 | e.printStackTrace(); 46 | } 47 | } 48 | } 49 | } 50 | 51 | public static void main(String[] args) { 52 | ServerSocket ss = null; 53 | try { 54 | // 创建一个服务器 Socket 55 | ss = new ServerSocket(PORT); 56 | while (true){ 57 | // 监听新的连接请求 58 | Socket conn = ss.accept(); 59 | System.out.println("Accept a new connection:" 60 | + conn.getRemoteSocketAddress().toString()); 61 | Thread t = new Thread(new TCPServerPerThread(conn)); 62 | t.start(); 63 | } 64 | } catch (IOException e) { 65 | e.printStackTrace(); 66 | } finally { 67 | if (ss != null){ 68 | try { 69 | ss.close(); 70 | } catch (IOException e) { 71 | e.printStackTrace(); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/multithreadserver/TCPServerThreadPool.java: -------------------------------------------------------------------------------- 1 | package com.haska.multithreadserver; 2 | 3 | import java.io.*; 4 | import java.net.ServerSocket; 5 | import java.net.Socket; 6 | import java.util.concurrent.Callable; 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.Executors; 9 | 10 | public class TCPServerThreadPool{ 11 | // 服务监听端口号 12 | private static final int PORT =56002; 13 | // 开启线程数 14 | private static final int THREAD_NUMS = 20; 15 | private static ExecutorService pool = null; 16 | 17 | // 创建一个 socket Task 类,处理数据收发 18 | private static class SockTask implements Callable { 19 | private Socket sock = null; 20 | 21 | public SockTask(Socket sock){ 22 | this.sock = sock; 23 | } 24 | @Override 25 | public Void call() throws Exception { 26 | // 读取客户端数据 27 | try { 28 | while (true){ 29 | // 读取客户端数据 30 | DataInputStream in = new DataInputStream( 31 | new BufferedInputStream(sock.getInputStream())); 32 | int msgLen = in.readInt(); 33 | byte[] inMessage = new byte[msgLen]; 34 | in.read(inMessage); 35 | System.out.println("Recv from client:" + new String(inMessage) + "length:" + msgLen); 36 | 37 | // 向客户端发送数据 38 | String rsp = "Hello Client!\n"; 39 | DataOutputStream out = new DataOutputStream( 40 | new BufferedOutputStream(sock.getOutputStream())); 41 | out.writeInt(rsp.getBytes().length); 42 | out.write(rsp.getBytes()); 43 | out.flush(); 44 | System.out.println("Send to client:" + rsp + " length:" + rsp.getBytes().length); 45 | } 46 | } catch (IOException e) { 47 | e.printStackTrace(); 48 | } finally { 49 | if (sock != null){ 50 | try { 51 | sock.close(); 52 | } catch (IOException e) { 53 | e.printStackTrace(); 54 | } 55 | } 56 | } 57 | return null; 58 | } 59 | } 60 | 61 | public static void main(String[] args) { 62 | ServerSocket ss = null; 63 | try { 64 | pool = Executors.newFixedThreadPool(THREAD_NUMS); 65 | // 创建一个服务器 Socket 66 | ss = new ServerSocket(PORT); 67 | while (true){ 68 | // 监听新的连接请求 69 | Socket conn = ss.accept(); 70 | System.out.println("Accept a new connection:" 71 | + conn.getRemoteSocketAddress().toString()); 72 | pool.submit(new SockTask(conn)); 73 | } 74 | } catch (IOException e) { 75 | e.printStackTrace(); 76 | } finally { 77 | if (ss != null){ 78 | try { 79 | ss.close(); 80 | } catch (IOException e) { 81 | e.printStackTrace(); 82 | } 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/netaddr/NetAddrDemo.java: -------------------------------------------------------------------------------- 1 | package com.haska.netaddr; 2 | 3 | import java.net.*; 4 | 5 | public class NetAddrDemo { 6 | public static void testInetAddressByAddr() 7 | { 8 | byte[] ips = new byte[]{ (byte)192, (byte)168,1,101}; 9 | try { 10 | InetAddress addr = InetAddress.getByAddress(ips); 11 | System.out.println("getByAddress addr=" + addr.toString()); 12 | 13 | InetAddress addr2 = InetAddress.getByAddress("www.example.com", ips); 14 | System.out.println("getByAddress with host addr=" + addr2.toString()); 15 | } catch (UnknownHostException e) { 16 | e.printStackTrace(); 17 | } 18 | } 19 | public static void testInetAddressByName(String host){ 20 | try { 21 | InetAddress addr = InetAddress.getByName(host); 22 | System.out.println("getByName addr=" + addr.toString()); 23 | 24 | InetAddress[] addrs = InetAddress.getAllByName(host); 25 | for (InetAddress a: addrs){ 26 | System.out.println("getAllByName addr=" + a.toString()); 27 | } 28 | } catch (UnknownHostException e) { 29 | e.printStackTrace(); 30 | } 31 | } 32 | public static void main(String[] args) { 33 | testInetAddressByName("www.imooc.com"); 34 | testInetAddressByName("www.imooc1.com"); 35 | testInetAddressByName("www.imoocabc.com"); 36 | //InetSocketAddress 37 | //java.net.Inet4Address 38 | testInetAddressByAddr(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/CustomEventObject.java: -------------------------------------------------------------------------------- 1 | package com.haska.network; 2 | 3 | import java.util.EventObject; 4 | 5 | public class CustomEventObject extends EventObject{ 6 | /** 7 | * 8 | */ 9 | private static final long serialVersionUID = -5732376546950130991L; 10 | 11 | // The string type 12 | protected String type; 13 | 14 | // The process listener 15 | protected Listener listener; 16 | 17 | public CustomEventObject(Object src, Listener l, String t){ 18 | super(src); 19 | this.type = t; 20 | this.listener = l; 21 | } 22 | 23 | public Listener listen(){return listener;} 24 | public String type(){return type;} 25 | } 26 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/IOAdapter.java: -------------------------------------------------------------------------------- 1 | package com.haska.network; 2 | 3 | import com.haska.network.impl.SocketHandler; 4 | 5 | public interface IOAdapter { 6 | public void onConnected(); 7 | public IOAdapter onAccept(); 8 | public void setSocketHandler(SocketHandler sh); 9 | public void onRead(); 10 | public void onWrite(); 11 | public void onClose(); 12 | } 13 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/IOHandler.java: -------------------------------------------------------------------------------- 1 | package com.haska.network; 2 | 3 | import java.nio.channels.spi.AbstractSelectableChannel; 4 | 5 | public interface IOHandler { 6 | public void handle_read(); 7 | 8 | public void handle_write(); 9 | 10 | public void handle_connected(); 11 | 12 | public void handle_accept(); 13 | 14 | public AbstractSelectableChannel getSocketChannel(); 15 | } 16 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/Listener.java: -------------------------------------------------------------------------------- 1 | package com.haska.network; 2 | 3 | import java.util.EventListener; 4 | 5 | public interface Listener extends EventListener { 6 | public void process(CustomEventObject eo); 7 | } 8 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/impl/AbstractAdapter.java: -------------------------------------------------------------------------------- 1 | package com.haska.network.impl; 2 | 3 | import com.haska.network.IOAdapter; 4 | 5 | public class AbstractAdapter implements IOAdapter { 6 | protected SocketHandler sockhandler = null; 7 | @Override 8 | public void onConnected() { 9 | // TODO Auto-generated method stub 10 | 11 | } 12 | 13 | @Override 14 | public IOAdapter onAccept() { 15 | // TODO Auto-generated method stub 16 | return null; 17 | } 18 | 19 | @Override 20 | public void onRead() { 21 | // TODO Auto-generated method stub 22 | 23 | } 24 | 25 | @Override 26 | public void onWrite() { 27 | // TODO Auto-generated method stub 28 | 29 | } 30 | 31 | @Override 32 | public void onClose() { 33 | // TODO Auto-generated method stub 34 | 35 | } 36 | 37 | public void setSocketHandler(SocketHandler sh){ 38 | sockhandler = sh; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/impl/Acceptor.java: -------------------------------------------------------------------------------- 1 | package com.haska.network.impl; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.nio.channels.ClosedChannelException; 6 | import java.nio.channels.SelectionKey; 7 | import java.nio.channels.ServerSocketChannel; 8 | import java.nio.channels.SocketChannel; 9 | import java.nio.channels.spi.AbstractSelectableChannel; 10 | 11 | import com.haska.network.CustomEventObject; 12 | import com.haska.network.IOAdapter; 13 | import com.haska.network.Listener; 14 | 15 | public class Acceptor extends SocketHandler implements Listener{ 16 | private ServerSocketChannel ssc_; 17 | 18 | public Acceptor(IOThread io_thr, IOAdapter io_adp){ 19 | super(io_thr, io_adp); 20 | } 21 | 22 | /** 23 | * Open the server socket 24 | * @param port the listen port 25 | * @return 26 | */ 27 | public void start(int port) throws IOException{ 28 | this.start(null, port); 29 | } 30 | 31 | /** 32 | * Open the server socket 33 | * @param hostname the host name 34 | * @param port the listen port 35 | * @return 1 if success, otherwise -1. 36 | */ 37 | public void start(String hostname, int port) throws IOException{ 38 | ssc_ = ServerSocketChannel.open(); 39 | InetSocketAddress addr; 40 | if (hostname == null || hostname.isEmpty()) { 41 | addr = new InetSocketAddress(port); 42 | } else { 43 | addr = new InetSocketAddress(hostname, port); 44 | } 45 | ssc_.socket().bind(addr); 46 | ssc_.socket().setReuseAddress(true); 47 | ssc_.configureBlocking(false); 48 | 49 | // Add listener to plug 50 | io_thr().addListener(new CustomEventObject(this, this, "plug")); 51 | } 52 | 53 | public void stop(){ 54 | try{ 55 | ssc_.close(); 56 | } catch (IOException ie){ 57 | ie.printStackTrace(); 58 | } catch (Exception e){ 59 | e.printStackTrace(); 60 | } 61 | } 62 | 63 | public void handle_accept() 64 | { 65 | try { 66 | SocketChannel asc = ssc_.accept(); 67 | 68 | IOAdapter ioadp = io_adp_.onAccept(); 69 | SocketHandler sh = new TcpHandler(io_thr(), ioadp); 70 | asc.configureBlocking(false); 71 | sh.accept(asc); 72 | ioadp.setSocketHandler(sh); 73 | } catch (IOException e) { 74 | e.printStackTrace(); 75 | } catch (Exception e){ 76 | e.printStackTrace(); 77 | } 78 | } 79 | 80 | public AbstractSelectableChannel getSocketChannel() 81 | { 82 | return ssc_; 83 | } 84 | 85 | @Override 86 | public void process(CustomEventObject eo) { 87 | try { 88 | if (eo.type().equals("plug")) { 89 | registerEvent(SelectionKey.OP_ACCEPT); 90 | } 91 | } catch (ClosedChannelException e) { 92 | e.printStackTrace(); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/impl/IOThread.java: -------------------------------------------------------------------------------- 1 | package com.haska.network.impl; 2 | 3 | import java.io.IOException; 4 | import java.util.concurrent.ConcurrentLinkedQueue; 5 | 6 | import com.haska.network.CustomEventObject; 7 | 8 | public class IOThread { 9 | private Poller poller_ = new Poller(); 10 | private boolean stop_ = false; 11 | private Worker worker = null; 12 | private ConcurrentLinkedQueue listener = new ConcurrentLinkedQueue(); 13 | 14 | public Poller getPoller(){return poller_;} 15 | 16 | public void start() throws IOException{ 17 | poller_.start(); 18 | 19 | // Start worker 20 | worker = new Worker(); 21 | worker.start(); 22 | } 23 | 24 | public void addListener(CustomEventObject e){ 25 | listener.offer(e); 26 | poller_.wakeup(); 27 | } 28 | 29 | public void stop(){ 30 | try { 31 | stop_ = true; 32 | poller_.wakeup(); 33 | worker.join(); 34 | } catch (InterruptedException e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | 39 | void dispatchListeners(){ 40 | while (!listener.isEmpty()){ 41 | CustomEventObject e = listener.poll(); 42 | e.listen().process(e); 43 | } 44 | } 45 | class Worker extends Thread{ 46 | @Override 47 | public void run() { 48 | while(!stop_){ 49 | try{ 50 | dispatchListeners(); 51 | poller_.poll(); 52 | } catch (IOException e){ 53 | e.printStackTrace(); 54 | } 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/impl/Poller.java: -------------------------------------------------------------------------------- 1 | package com.haska.network.impl; 2 | 3 | import java.io.IOException; 4 | import java.nio.channels.ClosedChannelException; 5 | import java.nio.channels.SelectionKey; 6 | import java.nio.channels.Selector; 7 | import java.util.Iterator; 8 | import java.util.Set; 9 | 10 | public class Poller { 11 | private Selector nio_selector_; 12 | 13 | public void start() throws IOException{ 14 | nio_selector_ = Selector.open(); 15 | } 16 | 17 | public SelectionKey register(SocketHandler sh, int ops) throws ClosedChannelException{ 18 | return sh.getSocketChannel().register(nio_selector_, ops, sh); 19 | } 20 | public void poll() throws IOException{ 21 | int readyChannels = nio_selector_.select(); 22 | 23 | if (readyChannels == 0) 24 | return; 25 | 26 | Set selectedKeys = nio_selector_.selectedKeys(); 27 | 28 | Iterator keyIterator = selectedKeys.iterator(); 29 | 30 | while (keyIterator.hasNext()) { 31 | SelectionKey key = keyIterator.next(); 32 | SocketHandler sh = (SocketHandler) key.attachment(); 33 | if (sh != null) { 34 | if (key.isAcceptable()) { 35 | // a connection was accepted by a ServerSocketChannel. 36 | sh.handle_accept(); 37 | } else if (key.isConnectable()) { 38 | // a connection was established with a remote server. 39 | sh.handle_connected(); 40 | } else if (key.isReadable()) { 41 | // a channel is ready for reading 42 | sh.handle_read(); 43 | } else if (key.isWritable()) { 44 | // a channel is ready for writing 45 | sh.handle_write(); 46 | } 47 | } 48 | keyIterator.remove(); 49 | } 50 | } 51 | 52 | public void wakeup(){ 53 | nio_selector_.wakeup(); 54 | } 55 | 56 | public void close() throws IOException{ 57 | this.nio_selector_.close(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/impl/SocketHandler.java: -------------------------------------------------------------------------------- 1 | package com.haska.network.impl; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.ClosedChannelException; 6 | import java.nio.channels.SelectionKey; 7 | import java.nio.channels.SocketChannel; 8 | import java.nio.channels.spi.AbstractSelectableChannel; 9 | 10 | import com.haska.network.IOAdapter; 11 | import com.haska.network.IOHandler; 12 | 13 | public class SocketHandler implements IOHandler{ 14 | private SelectionKey sk_ = null; 15 | protected SocketChannel sc_; 16 | protected IOThread io_thr_; 17 | protected IOAdapter io_adp_; 18 | 19 | public IOThread io_thr(){return io_thr_;} 20 | 21 | public SocketHandler(IOThread io_thr, IOAdapter io_adp){ 22 | io_thr_ = io_thr; 23 | io_adp_ = io_adp; 24 | } 25 | 26 | public void registerEvent(int ops) throws ClosedChannelException { 27 | if (sk_ == null) { 28 | sk_ = io_thr_.getPoller().register(this, ops); 29 | } else { 30 | sk_.interestOps(sk_.interestOps() | ops); 31 | } 32 | } 33 | 34 | public void cancelEvent(int ops) throws ClosedChannelException { 35 | if (sk_ == null) 36 | return; 37 | 38 | sk_.interestOps(sk_.interestOps() & (~ops)); 39 | } 40 | 41 | // IOHandler's methods 42 | public void handle_read() 43 | { 44 | 45 | } 46 | public void handle_write() 47 | { 48 | 49 | } 50 | public void handle_timeout(long timerid) 51 | { 52 | 53 | } 54 | public void handle_connected() 55 | { 56 | 57 | } 58 | public void handle_accept() 59 | { 60 | 61 | } 62 | 63 | public AbstractSelectableChannel getSocketChannel() 64 | { 65 | return sc_; 66 | } 67 | 68 | // Need override by subclass 69 | public boolean connect(String hostname, int port) throws IOException{return false;} 70 | public void accept(SocketChannel sc) throws IOException,ClosedChannelException {} 71 | public int send(ByteBuffer buff)throws IOException{return -1;} 72 | public int recv(ByteBuffer buff)throws IOException{return -1;} 73 | public void close(){ 74 | try{ 75 | sk_.cancel(); 76 | sc_.close(); 77 | }catch(IOException e){ 78 | ; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/impl/TcpHandler.java: -------------------------------------------------------------------------------- 1 | package com.haska.network.impl; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.nio.ByteBuffer; 6 | import java.nio.channels.ClosedChannelException; 7 | import java.nio.channels.SelectionKey; 8 | import java.nio.channels.SocketChannel; 9 | 10 | import com.haska.network.IOAdapter; 11 | 12 | public class TcpHandler extends SocketHandler { 13 | public TcpHandler(IOThread io_thr, IOAdapter io_adp){ 14 | super(io_thr, io_adp); 15 | } 16 | public boolean connect(String hostname, int port) throws IOException{ 17 | sc_ = SocketChannel.open(); 18 | sc_.configureBlocking(false); 19 | if (sc_.connect(new InetSocketAddress(hostname, port))){ 20 | return true; 21 | } 22 | 23 | // Register non-blocking connect events 24 | registerEvent(SelectionKey.OP_CONNECT); 25 | return false; 26 | } 27 | 28 | public void handle_connected() { 29 | try { 30 | if (sc_.finishConnect()) { 31 | io_adp_.onConnected(); 32 | registerEvent(SelectionKey.OP_READ); 33 | } 34 | }catch(ClosedChannelException e){ 35 | e.printStackTrace(); 36 | io_adp_.onClose(); 37 | }catch(IOException e){ 38 | e.printStackTrace(); 39 | io_adp_.onClose(); 40 | } 41 | } 42 | 43 | public void handle_read() 44 | { 45 | // Read data 46 | io_adp_.onRead(); 47 | } 48 | public void handle_write() 49 | { 50 | try{ 51 | cancelEvent(SelectionKey.OP_WRITE); 52 | io_adp_.onWrite(); 53 | }catch(ClosedChannelException e){ 54 | e.printStackTrace(); 55 | io_adp_.onClose(); 56 | } 57 | } 58 | 59 | public void accept(SocketChannel sc) throws IOException,ClosedChannelException { 60 | sc_ = sc; 61 | registerEvent(SelectionKey.OP_READ); 62 | } 63 | public int send(ByteBuffer buff)throws IOException{ 64 | return sc_.write(buff); 65 | } 66 | public int recv(ByteBuffer buff)throws IOException{ 67 | return sc_.read(buff); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/network/impl/ThreadPool.java: -------------------------------------------------------------------------------- 1 | package com.haska.network.impl; 2 | 3 | import java.io.IOException; 4 | 5 | public class ThreadPool { 6 | private static ThreadPool instance_ = new ThreadPool(); 7 | 8 | private IOThread[] thrs_; 9 | private int thr_num; 10 | private int cur_index = 0; 11 | private ThreadPool(){} 12 | 13 | public void initialize(int thr_num){ 14 | this.thr_num = thr_num; 15 | thrs_ = new IOThread[thr_num]; 16 | try { 17 | for (int i = 0; i < thr_num; i++) { 18 | thrs_[i] = new IOThread(); 19 | thrs_[i].start(); 20 | } 21 | } catch (IOException e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | public void destroy(){ 27 | for(IOThread iothr: thrs_){ 28 | iothr.stop(); 29 | } 30 | } 31 | public static ThreadPool getInstance(){ 32 | return instance_; 33 | } 34 | 35 | public IOThread getIOThread(){ 36 | IOThread thr = thrs_[cur_index++]; 37 | cur_index %= thr_num; 38 | return thr; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/nonblock/NonblockTCPClient.java: -------------------------------------------------------------------------------- 1 | package com.haska.nonblock; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.net.SocketAddress; 6 | import java.nio.ByteBuffer; 7 | import java.nio.channels.SocketChannel; 8 | import java.text.SimpleDateFormat; 9 | import java.util.Date; 10 | 11 | public class NonblockTCPClient { 12 | // 服务器监听的端口 13 | private final static int PORT = 9082; 14 | 15 | public static void main(String[] args) { 16 | SocketChannel sock = null; 17 | try { 18 | // 创建服务器地址结构 19 | SocketAddress serverAddr = new InetSocketAddress("127.0.0.1", PORT); 20 | sock = SocketChannel.open(serverAddr); 21 | 22 | ByteBuffer recvBuff = ByteBuffer.allocate(1024); 23 | ByteBuffer sendBuff = ByteBuffer.allocate(1024); 24 | 25 | int rquest_times = 10; 26 | 27 | while (true){ 28 | SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 29 | String request = "Request time"+ df.format(new Date()); 30 | sendBuff.putInt(request.length()); 31 | sendBuff.put(request.getBytes()); 32 | 33 | sendBuff.flip(); 34 | sock.write(sendBuff); 35 | 36 | System.out.println("Send request to server"); 37 | int bodyLen = -1; 38 | boolean isFlip = true; 39 | recvBuff.rewind(); 40 | 41 | while (true){ 42 | int rbytes = sock.read(recvBuff); 43 | if (rbytes == -1){ 44 | sock.close(); 45 | return; 46 | } 47 | 48 | if (bodyLen == -1){ 49 | if (rbytes < 4){ 50 | continue; 51 | } 52 | recvBuff.flip(); 53 | 54 | bodyLen = recvBuff.getInt(); 55 | isFlip =false; 56 | } 57 | 58 | if (isFlip ){ 59 | recvBuff.flip(); 60 | } 61 | if (recvBuff.remaining() < bodyLen){ 62 | recvBuff.compact(); 63 | continue; 64 | } 65 | 66 | byte[] body = new byte[bodyLen]; 67 | recvBuff.get(body); 68 | 69 | System.out.println("Recv server :" + new String(body, 0, bodyLen)); 70 | break; 71 | } 72 | 73 | if (rquest_times-- == 0) { 74 | break; 75 | } 76 | 77 | try { 78 | Thread.sleep(1000); 79 | } catch (InterruptedException e) { 80 | e.printStackTrace(); 81 | } 82 | 83 | sendBuff.rewind(); 84 | } 85 | } catch (IOException e) { 86 | e.printStackTrace(); 87 | try { 88 | if (sock != null){ 89 | sock.close(); 90 | } 91 | } catch (IOException e1) { 92 | e1.printStackTrace(); 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/sockoption/SockOptions.java: -------------------------------------------------------------------------------- 1 | package com.haska.sockoption; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.net.ServerSocket; 6 | import java.net.Socket; 7 | 8 | 9 | public class SockOptions { 10 | public static void main(String[] args) { 11 | ServerSocket ss = null; 12 | try { 13 | ss = new ServerSocket(); 14 | ss.setReuseAddress(true); 15 | ss.bind(new InetSocketAddress(8022)); 16 | Socket sock = ss.accept(); 17 | sock.setKeepAlive(true); 18 | sock.setSoLinger(true, 20); 19 | sock.setSendBufferSize(16384); 20 | sock.setReceiveBufferSize(16384); 21 | sock.setOOBInline(true); 22 | sock.setTcpNoDelay(true); 23 | } catch (IOException e) { 24 | e.printStackTrace(); 25 | } finally { 26 | if (ss != null){ 27 | try { 28 | ss.close(); 29 | } catch (IOException e) { 30 | e.printStackTrace(); 31 | } 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/tcp/TCPClient.java: -------------------------------------------------------------------------------- 1 | package com.haska.tcp; 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.BufferedOutputStream; 5 | import java.io.IOException; 6 | import java.io.OutputStream; 7 | import java.net.InetSocketAddress; 8 | import java.net.Socket; 9 | import java.net.SocketAddress; 10 | 11 | public class TCPClient { 12 | // 服务器监听的端口号 13 | private static final int PORT = 56002; 14 | private static final int TIMEOUT = 15000; 15 | 16 | public static void main(String[] args) { 17 | Socket client = null; 18 | try { 19 | // 在构造方法中传入 host 和 port 20 | // client = new Socket("192.168.43.49", PORT); 21 | 22 | // 调用无参构造方法 23 | client = new Socket(); 24 | // 构造服务器地址结构 25 | SocketAddress serverAddr = new InetSocketAddress("192.168.0.101", PORT); 26 | // 连接服务器,超时时间是 15 毫秒 27 | client.connect(serverAddr, TIMEOUT); 28 | 29 | System.out.println("Client start:" + client.getLocalSocketAddress().toString()); 30 | 31 | // 向服务器发送数据 32 | OutputStream out = new BufferedOutputStream(client.getOutputStream()); 33 | String req = "Hello Server!\n"; 34 | out.write(req.getBytes()); 35 | // 不能忘记 flush 方法的调用 36 | out.flush(); 37 | System.out.println("Send to server:" + req); 38 | 39 | // 接收服务器的数据 40 | BufferedInputStream in = new BufferedInputStream(client.getInputStream()); 41 | StringBuilder inMessage = new StringBuilder(); 42 | while(true){ 43 | int c = in.read(); 44 | if (c == -1 || c == '\n') 45 | break; 46 | inMessage.append((char)c); 47 | } 48 | System.out.println("Recv from server:" + inMessage.toString()); 49 | } catch (IOException e) { 50 | e.printStackTrace(); 51 | } finally { 52 | if (client != null){ 53 | try { 54 | client.close(); 55 | } catch (IOException e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/tcp/TCPServer.java: -------------------------------------------------------------------------------- 1 | package com.haska.tcp; 2 | 3 | import java.io.*; 4 | import java.net.ServerSocket; 5 | import java.net.Socket; 6 | 7 | public class TCPServer { 8 | private static final int PORT =56002; 9 | 10 | public static void main(String[] args) { 11 | ServerSocket ss = null; 12 | try { 13 | // 创建一个服务器 Socket 14 | ss = new ServerSocket(PORT); 15 | // 监听新的连接请求 16 | Socket conn = ss.accept(); 17 | System.out.println("Accept a new connection:" + conn.getRemoteSocketAddress().toString()); 18 | 19 | // 读取客户端数据 20 | BufferedInputStream in = new BufferedInputStream(conn.getInputStream()); 21 | StringBuilder inMessage = new StringBuilder(); 22 | while(true){ 23 | int c = in.read(); 24 | if (c == -1 || c == '\n') 25 | break; 26 | inMessage.append((char)c); 27 | } 28 | System.out.println("Recv from client:" + inMessage.toString()); 29 | 30 | // 向客户端发送数据 31 | String rsp = "Hello Client!\n"; 32 | BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream()); 33 | out.write(rsp.getBytes()); 34 | out.flush(); 35 | System.out.println("Send to client:" + rsp); 36 | conn.close(); 37 | } catch (IOException e) { 38 | e.printStackTrace(); 39 | } finally { 40 | if (ss != null){ 41 | try { 42 | ss.close(); 43 | } catch (IOException e) { 44 | e.printStackTrace(); 45 | } 46 | } 47 | } 48 | 49 | System.out.println("Server exit!"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/tcpio/TCPClientIO.java: -------------------------------------------------------------------------------- 1 | package com.haska.tcpio; 2 | 3 | import java.io.*; 4 | import java.net.InetSocketAddress; 5 | import java.net.Socket; 6 | import java.net.SocketAddress; 7 | 8 | public class TCPClientIO { 9 | // 服务器监听的端口号 10 | private static final int PORT = 56002; 11 | private static final int TIMEOUT = 15000; 12 | 13 | public static void main(String[] args) { 14 | Socket client = null; 15 | try { 16 | // 调用无参构造方法 17 | client = new Socket(); 18 | // 构造服务器地址结构 19 | SocketAddress serverAddr = new InetSocketAddress("127.0.0.1", PORT); 20 | // 连接服务器,超时时间是 15 毫秒 21 | client.connect(serverAddr, TIMEOUT); 22 | 23 | System.out.println("Client start:" + client.getLocalSocketAddress().toString()); 24 | 25 | // 向服务器发送数据 26 | DataOutputStream out = new DataOutputStream( 27 | new BufferedOutputStream(client.getOutputStream())); 28 | String req = "Hello Server!\n"; 29 | out.writeInt(req.getBytes().length); 30 | out.write(req.getBytes()); 31 | // 不能忘记 flush 方法的调用 32 | out.flush(); 33 | System.out.println("Send to server:" + req + " length:" +req.getBytes().length); 34 | 35 | // 接收服务器的数据 36 | DataInputStream in = new DataInputStream( 37 | new BufferedInputStream(client.getInputStream())); 38 | 39 | int msgLen = in.readInt(); 40 | byte[] inMessage = new byte[msgLen]; 41 | in.read(inMessage); 42 | System.out.println("Recv from server:" + new String(inMessage) + " length:" + msgLen); 43 | } catch (IOException e) { 44 | e.printStackTrace(); 45 | } finally { 46 | if (client != null){ 47 | try { 48 | client.close(); 49 | } catch (IOException e) { 50 | e.printStackTrace(); 51 | } 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/tcpio/TCPServerIO.java: -------------------------------------------------------------------------------- 1 | package com.haska.tcpio; 2 | 3 | import java.io.*; 4 | import java.net.ServerSocket; 5 | import java.net.Socket; 6 | import java.io.BufferedInputStream; 7 | import java.io.DataInputStream; 8 | import java.io.BufferedOutputStream; 9 | import java.io.DataOutputStream; 10 | 11 | public class TCPServerIO { 12 | private static final int PORT =56002; 13 | 14 | public static void main(String[] args) { 15 | ServerSocket ss = null; 16 | try { 17 | // 创建一个服务器 Socket 18 | ss = new ServerSocket(PORT); 19 | // 监听新的连接请求 20 | Socket conn = ss.accept(); 21 | System.out.println("Accept a new connection:" + conn.getRemoteSocketAddress().toString()); 22 | 23 | // 读取客户端数据 24 | DataInputStream in = new DataInputStream( 25 | new BufferedInputStream(conn.getInputStream())); 26 | int msgLen = in.readInt(); 27 | byte[] inMessage = new byte[msgLen]; 28 | in.read(inMessage); 29 | System.out.println("Recv from client:" + new String(inMessage) + "length:" + msgLen); 30 | 31 | // 向客户端发送数据 32 | String rsp = "Hello Client!\n"; 33 | 34 | DataOutputStream out = new DataOutputStream( 35 | new BufferedOutputStream(conn.getOutputStream())); 36 | out.writeInt(rsp.getBytes().length); 37 | out.write(rsp.getBytes()); 38 | out.flush(); 39 | System.out.println("Send to client:" + rsp + " length:" + rsp.getBytes().length); 40 | conn.close(); 41 | } catch (IOException e) { 42 | e.printStackTrace(); 43 | } finally { 44 | if (ss != null){ 45 | try { 46 | ss.close(); 47 | } catch (IOException e) { 48 | e.printStackTrace(); 49 | } 50 | } 51 | } 52 | 53 | System.out.println("Server exit!"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/udp/UDPClient.java: -------------------------------------------------------------------------------- 1 | package com.haska.udp; 2 | 3 | import java.io.IOException; 4 | import java.net.DatagramPacket; 5 | import java.net.DatagramSocket; 6 | import java.net.InetSocketAddress; 7 | import java.net.SocketAddress; 8 | 9 | public class UDPClient { 10 | private static final int PORT = 9002; 11 | private static final String DST_HOST = "127.0.0.1"; 12 | private static final int RECV_BUFF_LEN = 1500; 13 | private static byte[] inBuff = new byte[RECV_BUFF_LEN]; 14 | 15 | public static void main(String[] args) { 16 | // 创建 UDP 客户端 Socket,选择无参构造方法,由系统分配本地端口号和网络接口 17 | try (DatagramSocket udpClient = new DatagramSocket()){ 18 | // 构造发送的目标地址,指定目标 IP 和目标端口号 19 | SocketAddress to = new InetSocketAddress(DST_HOST, PORT); 20 | while (true){ 21 | String req = "Hello Server!"; 22 | // 构造发送数据包,需要传入消息内容和目标地址结构 SocketAddress 23 | DatagramPacket message = new DatagramPacket(req.getBytes(), req.length(), to); 24 | // 发送消息 25 | udpClient.send(message); 26 | System.out.println("Send UDP message:" 27 | + req + " to server:" + message.getSocketAddress().toString()); 28 | 29 | // 构造接收消息的数据包,需要传入 byte 数组 30 | DatagramPacket inMessage = new DatagramPacket(inBuff, inBuff.length); 31 | // 接收消息 32 | udpClient.receive(inMessage); 33 | 34 | System.out.println("Recv UDP message:" 35 | + new String(inMessage.getData(), 0, inMessage.getLength()) 36 | + " from server:" + inMessage.getSocketAddress().toString()); 37 | 38 | // 每隔 2 秒发送一次消息 39 | try { 40 | Thread.sleep(2000); 41 | } catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | } catch (IOException e) { 46 | e.printStackTrace(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/udp/UDPServer.java: -------------------------------------------------------------------------------- 1 | package com.haska.udp; 2 | 3 | import java.io.IOException; 4 | import java.net.DatagramPacket; 5 | import java.net.DatagramSocket; 6 | 7 | public class UDPServer { 8 | private static final int BIND_PORT = 9002; 9 | private static final String BIND_HOST = "127.0.0.1"; 10 | private static final int RECV_BUFF_LEN = 1500; 11 | private static byte[] inBuff = new byte[RECV_BUFF_LEN]; 12 | 13 | public static void main(String[] args) { 14 | // 构造服务器 Socket,绑定到一个固定的端口,监听的 IP 是 0.0.0.0 15 | try (DatagramSocket udpServer = new DatagramSocket(BIND_PORT)) { 16 | // 构造接收消息的数据包,需要传入 byte 数组。 17 | // 我们将这条语句放在循环外,不需要每次消息收发都构造此结构 18 | DatagramPacket inMessage = new DatagramPacket(inBuff, inBuff.length); 19 | while (true){ 20 | // 接收客户端消息 21 | udpServer.receive(inMessage); 22 | System.out.println("Recv UDP message:" 23 | + new String(inMessage.getData(), 0, inMessage.getLength()) 24 | + " from Client:" 25 | + inMessage.getSocketAddress().toString()); 26 | 27 | String rsp = "Hello Client!"; 28 | // 构造发送的消息结构 29 | // 注意!!!对于服务器来说,发送的目标地址一定是接收消息时的源地址,所以从 inMessage 结构获取 30 | DatagramPacket message = new DatagramPacket(rsp.getBytes(), rsp.length(), 31 | inMessage.getSocketAddress()); 32 | // 发送消息 33 | udpServer.send(message); 34 | System.out.println("Send UDP message:" 35 | + rsp + " to Client:" + message.getSocketAddress().toString()); 36 | // 重置接收数据包消息长度,准备接收下一个消息 37 | inMessage.setLength(inBuff.length); 38 | } 39 | } catch (IOException e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/udpio/UDPClientIO.java: -------------------------------------------------------------------------------- 1 | package com.haska.udpio; 2 | 3 | import java.io.*; 4 | import java.net.DatagramPacket; 5 | import java.net.DatagramSocket; 6 | import java.net.InetSocketAddress; 7 | import java.net.SocketAddress; 8 | 9 | public class UDPClientIO { 10 | private static final int PORT = 9002; 11 | private static final String DST_HOST = "127.0.0.1"; 12 | private static final int RECV_BUFF_LEN = 1500; 13 | private static byte[] inBuff = new byte[RECV_BUFF_LEN]; 14 | private static short sequence = 1; 15 | 16 | public static void main(String[] args) { 17 | // 创建 UDP 客户端 Socket,选择无参构造方法,由系统分配本地端口号和网络接口 18 | try (DatagramSocket udpClient = new DatagramSocket()){ 19 | // 构造发送的目标地址,指定目标 IP 和目标端口号 20 | SocketAddress to = new InetSocketAddress(DST_HOST, PORT); 21 | byte[] body = new byte[RECV_BUFF_LEN]; 22 | 23 | while (true){ 24 | String req = "Hello Server!"; 25 | Message sMsg = new Message(); 26 | sMsg.setVersion((byte)1); 27 | sMsg.setFlag((byte)21); 28 | sMsg.setSequence(sequence++); 29 | sMsg.setTimestamp((int)System.currentTimeMillis()&0xFFFFFFFF); 30 | sMsg.setBody(req.getBytes()); 31 | DatagramPacket outMessage = sMsg.serialize(); 32 | outMessage.setSocketAddress(to); 33 | // 发送消息 34 | udpClient.send(outMessage); 35 | System.out.println("Send UDP message:" 36 | + req + " to server:" + outMessage.getSocketAddress().toString()); 37 | 38 | // 构造接收消息的数据包,需要传入 byte 数组 39 | DatagramPacket inMessage = new DatagramPacket(inBuff, inBuff.length); 40 | // 接收消息 41 | udpClient.receive(inMessage); 42 | 43 | Message rMsg = new Message(); 44 | rMsg.deserialize(inMessage); 45 | System.out.println("Recv UDP " + rMsg 46 | + " from Client:" + inMessage.getSocketAddress().toString()); 47 | 48 | // 每隔 2 秒发送一次消息 49 | try { 50 | Thread.sleep(2000); 51 | } catch (InterruptedException e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | } catch (IOException e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /java_netprogramming/src/com/haska/udpio/UDPServerIO.java: -------------------------------------------------------------------------------- 1 | package com.haska.udpio; 2 | 3 | import java.io.*; 4 | import java.net.DatagramPacket; 5 | import java.net.DatagramSocket; 6 | import java.util.Random; 7 | 8 | public class UDPServerIO { 9 | private static final int BIND_PORT = 9002; 10 | private static final String BIND_HOST = "127.0.0.1"; 11 | private static final int RECV_BUFF_LEN = 1500; 12 | private static byte[] inBuff = new byte[RECV_BUFF_LEN]; 13 | private static final int SEND_BUFF_LEN = 512; 14 | private static ByteArrayOutputStream outArray = new ByteArrayOutputStream(SEND_BUFF_LEN); 15 | private static short sequence = 1000; 16 | 17 | public static void main(String[] args) { 18 | // 构造服务器 Socket,绑定到一个固定的端口,监听的 IP 是 0.0.0.0 19 | try (DatagramSocket udpServer = new DatagramSocket(BIND_PORT)) { 20 | // 构造接收消息的数据包,需要传入 byte 数组。 21 | // 我们将这条语句放在循环外,不需要每次消息收发都构造此结构 22 | DatagramPacket inMessage = new DatagramPacket(inBuff, inBuff.length); 23 | byte[] body = new byte[RECV_BUFF_LEN]; 24 | 25 | while (true){ 26 | // 接收客户端消息 27 | udpServer.receive(inMessage); 28 | Message rMsg = new Message(); 29 | rMsg.deserialize(inMessage); 30 | System.out.println("Recv UDP " + rMsg 31 | + " from Client:" + inMessage.getSocketAddress().toString()); 32 | 33 | String rsp = "Hello Client!"; 34 | Message sMsg = new Message(); 35 | sMsg.setVersion((byte)1); 36 | sMsg.setFlag((byte)21); 37 | sMsg.setSequence(sequence++); 38 | sMsg.setTimestamp((int)System.currentTimeMillis()&0xFFFFFFFF); 39 | sMsg.setBody(rsp.getBytes()); 40 | 41 | // 构造发送的消息结构 42 | // 注意!!!对于服务器来说,发送的目标地址一定是接收消息时的源地址,所以从 inMessage 结构获取 43 | DatagramPacket outMessage = sMsg.serialize(); 44 | outMessage.setSocketAddress(inMessage.getSocketAddress()); 45 | 46 | // 发送消息 47 | udpServer.send(outMessage); 48 | System.out.println("Send UDP message:" 49 | + rsp + " to Client:" + outMessage.getSocketAddress().toString()); 50 | // 重置接收数据包消息长度,准备接收下一个消息 51 | inMessage.setLength(inBuff.length); 52 | } 53 | } catch (IOException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | } 58 | --------------------------------------------------------------------------------