IOCP的程序

C代码  收藏代码
  1. #include <winsock2.h>  
  2. #include <mswsock.h>  
  3. #include <windows.h>  
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <assert.h>  
  7. #include "vld.h"  
  8.   
  9. #pragma message("automatic link to ws2_32.lib and mswsock.lib")  
  10. #pragma comment(lib, "ws2_32.lib")  
  11. #pragma comment(lib, "mswsock.lib")  
  12.   
  13.   
  14.   
  15.   
  16. #define RETURN_SUCESS (0)  
  17. #define RETURN_FAILED (-1)  
  18.   
  19. #define PORT 5150//端口  
  20. #define IOCP_THREAD_MAX 16//最大的线程数  
  21. #define DATA_BUFSIZE 8192  
  22.   
  23.   
  24.   
  25. //区别是何种完成事件  
  26. enum IO_EVENT  
  27. {  
  28.     IO_EVENT_ACCEPT,  
  29.     IO_EVENT_WSARECV,  
  30.     IO_EVENT_WSARECVFROM,  
  31.     //不支持异步发送  
  32.     //IO_EVENT_WSASEND,  
  33.     //IO_EVENT_WSASENDTO  
  34. };  
  35.   
  36.   
  37.   
  38.   
  39. typedef struct overlapped_wrapper  
  40. {  
  41.     //OVERLAPPED要放在第一个  
  42.     OVERLAPPED overlapped;  
  43.     int io_type;//指示是何种IO操作  
  44. }overlapped_wrapper;  
  45.   
  46.   
  47.   
  48. typedef struct acceptex_block  
  49. {  
  50.     //OVERLAPPED要放在第一个  
  51.     OVERLAPPED overlapped;  
  52.     int io_type;//指示是何种IO操作  
  53.   
  54.     char buffer[DATA_BUFSIZE];  
  55.     SOCKET listen_socket;  
  56.     SOCKET accept_socket;  
  57. }acceptex_block;  
  58.   
  59.   
  60.   
  61. typedef struct recv_block  
  62. {  
  63.     //OVERLAPPED要放在第一个  
  64.     OVERLAPPED overlapped;  
  65.     int io_type;//指示是何种IO操作  
  66.   
  67.     char buffer[DATA_BUFSIZE];  
  68.     SOCKET socket;  
  69.     WSABUF wsa_recv_buf;  
  70.     DWORD bytes_recveived;  
  71. }recv_block;  
  72.   
  73.   
  74.   
  75. typedef struct recvfrom_block  
  76. {  
  77.     //OVERLAPPED要放在第一个  
  78.     OVERLAPPED overlapped;  
  79.     int io_type;//指示是何种IO操作  
  80.   
  81.     char buffer[DATA_BUFSIZE];  
  82.     SOCKET socket;  
  83.     WSABUF wsa_recv_buf;  
  84.     DWORD bytes_recveived;  
  85.   
  86.     //UDP包的源地址  
  87.     struct sockaddr_in from_address;  
  88.     int from_address_len;  
  89. }recvfrom_block;  
  90.   
  91.   
  92.   
  93.   
  94.   
  95.   
  96. int get_cpu_number();  
  97.   
  98. int async_AcceptEx(acceptex_block* block);  
  99. int async_WSARecv(recv_block* block);  
  100. int async_WSARecvFrom(recvfrom_block* block);  
  101.   
  102. void on_acceptex(acceptex_block* block);  
  103. void on_recv(recv_block* block);  
  104. void on_recvfrom(recvfrom_block* block);  
  105. void on_tcp_listen_close(acceptex_block* block);  
  106. void on_tcp_close(recv_block* block);  
  107. void on_udp_close(recvfrom_block* block);  
  108.   
  109. int init(void);  
  110. void uninit(void);  
  111. DWORD WINAPI worker_thread(LPVOID CompletionPortID);  
  112. void exit_error();  
  113.   
  114.   
  115.   
  116.   
  117.   
  118. //完成端口的句柄  
  119. HANDLE g_completion_port = INVALID_HANDLE_VALUE;  
  120. //工作线程句柄  
  121. HANDLE g_threads[IOCP_THREAD_MAX];  
  122. //工作线程数量  
  123. int g_threads_number = 0;  
  124.   
  125.   
  126. int main(void)  
  127. {  
  128.     /************************************************************************/  
  129.     /*TCP的例子*/  
  130.     /************************************************************************/  
  131.     SOCKADDR_IN internet_address;  
  132.     SOCKET listen_socket;  
  133.     acceptex_block* block;  
  134.   
  135.     if(RETURN_FAILED == init())  
  136.         exit_error();  
  137.   
  138.     if ((listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)  
  139.         exit_error();  
  140.   
  141.     internet_address.sin_family = AF_INET;  
  142.     internet_address.sin_addr.s_addr = htonl(INADDR_ANY);  
  143.     internet_address.sin_port = htons(PORT);  
  144.   
  145.     if (bind(listen_socket, (PSOCKADDR) &internet_address, sizeof(internet_address)) == SOCKET_ERROR)  
  146.         exit_error();  
  147.   
  148.     if (listen(listen_socket, SOMAXCONN) == SOCKET_ERROR)  
  149.         exit_error();  
  150.   
  151.     printf("listening socket %d\n", PORT);  
  152.   
  153.     //把监听的SOCKET和完成端口绑定  
  154.     if(NULL == CreateIoCompletionPort((HANDLE)listen_socket, g_completion_port, (u_long)listen_socket, 0))  
  155.         exit_error();  
  156.   
  157.     block = (acceptex_block*)malloc(sizeof(acceptex_block));  
  158.     block->listen_socket = listen_socket;  
  159.     async_AcceptEx(block);  
  160.     getchar();  
  161.     closesocket(listen_socket);  
  162.     getchar();  
  163.     uninit();  
  164.     return 0;  
  165.   
  166.   
  167.   
  168.     /************************************************************************/  
  169.     /*UDP的例子*/  
  170.     /************************************************************************/  
  171.     //SOCKADDR_IN internet_address;  
  172.     //SOCKET sock;  
  173.     //recvfrom_block* block = (recvfrom_block*)malloc(sizeof(recvfrom_block));  
  174.   
  175.     //if(RETURN_FAILED == init())  
  176.     //  exit_error();  
  177.   
  178.     //if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)  
  179.     //  exit_error();  
  180.   
  181.     //internet_address.sin_family = AF_INET;  
  182.     //internet_address.sin_addr.s_addr = htonl(INADDR_ANY);  
  183.     //internet_address.sin_port = htons(PORT);  
  184.   
  185.     //if (bind(sock, (PSOCKADDR) &internet_address, sizeof(internet_address)) == SOCKET_ERROR)  
  186.     //  exit_error();  
  187.   
  188.     //if(NULL == CreateIoCompletionPort((HANDLE)sock, g_completion_port, (u_long)sock, 0))  
  189.     //  exit_error();  
  190.   
  191.     //block->socket = sock;  
  192.     //async_WSARecvFrom(block);  
  193.   
  194.   
  195.     //getchar();  
  196.     //closesocket(sock);  
  197.     //getchar();  
  198.     //uninit();  
  199.     //return 0;  
  200. }  
  201.   
  202.   
  203.   
  204.   
  205. int init(void)  
  206. {  
  207.     WSADATA wsa_data;  
  208.     int i;  
  209. #if defined _DEBUG || defined DEBUG  
  210.     //调试时用一个线程方便  
  211.     int threads = 1;  
  212. #else  
  213.     int threads = get_cpu_number();  
  214. #endif  
  215.   
  216.   
  217.     if (WSAStartup(0x0202, &wsa_data) != 0)  
  218.         return RETURN_FAILED;  
  219.   
  220.     //建立完成端口  
  221.     if ((g_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)  
  222.         return RETURN_FAILED;  
  223.   
  224.     if(threads > IOCP_THREAD_MAX)  
  225.         threads = IOCP_THREAD_MAX;  
  226.     for(i = 0; i < threads; i++)  
  227.     {  
  228.         //创建工作线程  
  229.         g_threads[g_threads_number++] = CreateThread(NULL, 0, worker_thread, NULL, 0, 0);  
  230.     }  
  231.     return RETURN_SUCESS;  
  232. }  
  233.   
  234.   
  235.   
  236. void uninit(void)  
  237. {  
  238.     //自定义的退出协议,三个参数全为0时退出  
  239.     PostQueuedCompletionStatus(g_completion_port, 0, 0, NULL);  
  240.   
  241.     WaitForMultipleObjects(g_threads_number, g_threads, TRUE, INFINITE);  
  242.   
  243.     CloseHandle(g_completion_port);  
  244.   
  245.     WSACleanup();  
  246. }  
  247.   
  248.   
  249. int get_cpu_number()  
  250. {  
  251.     SYSTEM_INFO system_info;  
  252.     GetSystemInfo(&system_info);  
  253.     return system_info.dwNumberOfProcessors;  
  254. }  
  255.   
  256.   
  257. void exit_error()  
  258. {  
  259.     int error = GetLastError();  
  260.     if (error == 0)  
  261.     {  
  262.         exit(RETURN_SUCESS);  
  263.     }  
  264.     else  
  265.     {  
  266.         fprintf(stderr, "error:%d\n", error);  
  267.         exit(RETURN_FAILED);  
  268.     }  
  269. }  
  270.   
  271.   
  272.   
  273. /* 
  274. 投递一次AcceptEx请求 
  275. 返回TRUE,成功 
  276. 返回FALSE,失败,WSAGetLastError()获取进一步信息 
  277. */  
  278. int async_AcceptEx(acceptex_block* block)  
  279. {  
  280.     DWORD address_length;  
  281.     DWORD bytes_received;  
  282.   
  283.     //准备投递一个异步接受请求  
  284.     SOCKET accept_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
  285.     if(accept_socket == INVALID_SOCKET)  
  286.         return RETURN_FAILED;  
  287.   
  288.     block->io_type = IO_EVENT_ACCEPT;  
  289.     block->accept_socket = accept_socket;  
  290.     memset(&block->overlapped, 0,   
  291.         sizeof(block->overlapped));  
  292.   
  293.   
  294.     address_length = sizeof(struct sockaddr_in) + 16;  
  295.     if(!AcceptEx(  
  296.         block->listen_socket,   
  297.         accept_socket,  
  298.         block->buffer,//这个参数会传递给完成端口  
  299.         0,//DATA_BUFSIZE - i * 2,       //传0进来,接受的连接的时候不接受数据  
  300.         address_length, address_length,  
  301.         &bytes_received,   
  302.         &block->overlapped))  
  303.     {  
  304.         if(WSAGetLastError() != ERROR_IO_PENDING)  
  305.             goto fail;  
  306.     }  
  307.     return RETURN_SUCESS;  
  308.   
  309. fail:  
  310.     closesocket(accept_socket);  
  311.     return RETURN_FAILED;  
  312. }  
  313.   
  314.   
  315.   
  316.   
  317.   
  318.   
  319.   
  320.   
  321. /* 
  322. 投递一次WSARecv请求 
  323. 返回TRUE,表示接受请求投递成功 
  324. 返回FALSE,表示连接已经断开,WSAGetLastError()获取进一步信息 
  325. */  
  326. int async_WSARecv(recv_block* block)  
  327. {  
  328.     int ret;  
  329.     DWORD recv_bytes, flags = 0;  
  330.   
  331.     block->io_type = IO_EVENT_WSARECV;  
  332.     block->bytes_recveived = 0;  
  333.     block->wsa_recv_buf.len = DATA_BUFSIZE;  
  334.     block->wsa_recv_buf.buf = block->buffer;  
  335.     memset(&(block->overlapped), 0, sizeof(block->overlapped));  
  336.   
  337.   
  338.     //投递一次接受请求  
  339.     ret = WSARecv(block->socket, &block->wsa_recv_buf, 1, &recv_bytes, &flags,  
  340.         &(block->overlapped), NULL);  
  341.   
  342.     if(ret == -1 && WSAGetLastError() != ERROR_IO_PENDING)  
  343.     {  
  344.         printf("WSARecv() error returns %d\n", ret);  
  345.         on_tcp_close(block);  
  346.         return RETURN_FAILED;  
  347.     }  
  348.     else if((ret == 0) || (ret == -1 && WSAGetLastError() == ERROR_IO_PENDING))  
  349.     {  
  350.         //waiting... for next turn  
  351.     }  
  352.     else  
  353.     {  
  354.         //如果直接收到了数据  
  355.         block->bytes_recveived = ret;  
  356.         on_recv(block);  
  357.         //递归  
  358.         return async_WSARecv(block);  
  359.     }  
  360.   
  361.     return RETURN_SUCESS;  
  362. }  
  363.   
  364.   
  365.   
  366.   
  367.   
  368. /* 
  369. 投递一次WSARecvFrom请求 
  370. 返回TRUE,表示接受请求投递成功 
  371. 返回FALSE,表示接受请求投递失败,WSAGetLastError()获取进一步信息 
  372. */  
  373. int async_WSARecvFrom(recvfrom_block* block)  
  374. {  
  375.     int ret;  
  376.     DWORD recv_bytes = 0, flags = 0;  
  377.   
  378.     block->io_type = IO_EVENT_WSARECVFROM;  
  379.     block->bytes_recveived = 0;  
  380.     block->wsa_recv_buf.len = DATA_BUFSIZE;  
  381.     block->wsa_recv_buf.buf = block->buffer;  
  382.     memset(&block->from_address, 0, sizeof(block->from_address));  
  383.     block->from_address_len = sizeof(block->from_address);  
  384.     memset(&(block->overlapped), 0, sizeof(block->overlapped));  
  385.   
  386.   
  387.     //投递一次接受请求  
  388.     ret = WSARecvFrom(block->socket, &block->wsa_recv_buf, 1, &recv_bytes, &flags,  
  389.         (struct sockaddr*)&block->from_address, &block->from_address_len,  
  390.         &(block->overlapped), NULL);  
  391.   
  392.     if(ret == -1 && WSAGetLastError() != ERROR_IO_PENDING)  
  393.     {  
  394.         printf("WSARecvFrom() error returns %d %d\n", ret, WSAGetLastError());  
  395.         on_udp_close(block);  
  396.         return RETURN_FAILED;  
  397.     }  
  398.     else if((ret == 0) || (ret == -1 && WSAGetLastError() == ERROR_IO_PENDING))  
  399.     {  
  400.         //waiting... for next turn  
  401.     }  
  402.     else  
  403.     {  
  404.         //如果直接收到了数据  
  405.         block->bytes_recveived = ret;  
  406.         on_recvfrom(block);  
  407.         //递归  
  408.         return async_WSARecvFrom(block);  
  409.     }  
  410.   
  411.     return RETURN_SUCESS;  
  412. }  
  413.   
  414.   
  415. void on_acceptex(acceptex_block* block)  
  416. {  
  417.     DWORD i;  
  418.     struct sockaddr *p_local_addr;  
  419.     int local_addr_len = sizeof(struct sockaddr_in);  
  420.     struct sockaddr *p_remote_addr;  
  421.     int remote_addr_len = sizeof(struct sockaddr_in);  
  422.     struct sockaddr_in *p_v4_addr;  
  423.   
  424.     recv_block* r_block;  
  425.   
  426.   
  427.     printf("on_acceptex %d\n", block->accept_socket);  
  428.   
  429.     i = sizeof(struct sockaddr_in) + 16;  
  430.     GetAcceptExSockaddrs(  
  431.         block->buffer,  
  432.         0,//DATA_BUFSIZE - i * 2,  
  433.         i, i,  
  434.         &p_local_addr,  
  435.         &local_addr_len,  
  436.         &p_remote_addr,  
  437.         &remote_addr_len  
  438.         );  
  439.   
  440.     p_v4_addr = (struct sockaddr_in *)p_local_addr;  
  441.     printf("\t本地地址%s:%d\n",   
  442.         inet_ntoa(p_v4_addr->sin_addr), ntohs(p_v4_addr->sin_port));  
  443.     p_v4_addr = (struct sockaddr_in *)p_remote_addr;  
  444.     printf("\t远程地址%s:%d\n",   
  445.         inet_ntoa(p_v4_addr->sin_addr), ntohs(p_v4_addr->sin_port));  
  446.   
  447.   
  448.   
  449.     //准备投递一次WSARecv请求  
  450.     r_block = (recv_block*)malloc(sizeof(recv_block));  
  451.     r_block->socket = block->accept_socket;  
  452.   
  453.     //绑定  
  454.     CreateIoCompletionPort((HANDLE)r_block->socket,   
  455.         g_completion_port, (u_long)r_block->socket, 0);  
  456.   
  457.     //投递一次接受请求  
  458.     async_WSARecv(r_block);  
  459.   
  460.     //继续投递AcceptEx请求  
  461.     async_AcceptEx(block);  
  462. }  
  463.   
  464. void on_recv(recv_block* block)  
  465. {  
  466.     printf("on_recv %d, 收到%d bytes数据\n", block->socket, block->bytes_recveived);  
  467.   
  468.     async_WSARecv(block);  
  469. }  
  470.   
  471.   
  472. void on_recvfrom(recvfrom_block* block)  
  473. {  
  474.     printf("on_recvfrom %d, 收到%d bytes数据, 来自%s:%d\n",  
  475.         block->socket,  
  476.         block->bytes_recveived,  
  477.         inet_ntoa(block->from_address.sin_addr),  
  478.         ntohs(block->from_address.sin_port));  
  479.   
  480.     async_WSARecvFrom(block);  
  481. }  
  482.   
  483.   
  484. void on_tcp_listen_close(acceptex_block* block)  
  485. {  
  486.     printf("on_tcp_listen_close %d\n", block->accept_socket);  
  487.     free(block);  
  488.     closesocket(block->accept_socket);  
  489. }  
  490.   
  491.   
  492. void on_tcp_close(recv_block* block)  
  493. {  
  494.     printf("on_tcp_close %d\n", block->socket);  
  495.     free(block);  
  496.     closesocket(block->socket);  
  497. }  
  498.   
  499.   
  500. void on_udp_close(recvfrom_block* block)  
  501. {  
  502.     printf("on_udp_close %d\n", block->socket);  
  503.     free(block);  
  504.     closesocket(block->socket);  
  505. }  
  506.   
  507.   
  508.   
  509. DWORD WINAPI worker_thread(LPVOID nothing)  
  510. {  
  511.     DWORD bytes;  
  512.     overlapped_wrapper* over_type;  
  513.     BOOL close_socket = FALSE;  
  514.     BOOL ret;  
  515.   
  516.     UNREFERENCED_PARAMETER(nothing);  
  517.   
  518.     for(;;)  
  519.     {  
  520.         SOCKET socket;  
  521.         //注意第三个参数,他是CreateIoCompletionPort时传入的,直接传入的是一个SOCKET  
  522.         //注意第四个参数,他可能是一个recv_block或acceptex_block结构的指针  
  523.         //因为OVERLAPPED是PER_IO_OPERATION_DATA的第一个成员,所以可以安全的进行转换  
  524.         ret = GetQueuedCompletionStatus(g_completion_port, &bytes,  
  525.             (LPDWORD)&socket, (LPOVERLAPPED *) &over_type, INFINITE);  
  526.   
  527.   
  528.         if(ret == ERROR_SUCCESS)  
  529.         {  
  530.             DWORD last_error = GetLastError();  
  531.   
  532.             if(ERROR_INVALID_HANDLE == last_error)  
  533.             {  
  534.                 printf("完成端口被关闭,退出\n");  
  535.                 return 0;  
  536.             }  
  537.             else if(ERROR_NETNAME_DELETED == last_error  
  538.                 || ERROR_OPERATION_ABORTED == last_error)  
  539.             {  
  540.                 printf("socket被关闭 或者 操作被取消\n");  
  541.                 close_socket = TRUE;  
  542.             }  
  543.             else  
  544.             {  
  545.                 printf("GetLastError %d\n", last_error);  
  546.                 continue;  
  547.             }  
  548.         }  
  549.         //自定义的退出协议,三个参数全为0时退出(见uninit中的PostQueuedCompletionStatus)  
  550.         else if(bytes == 0 && socket == 0 && over_type == NULL)  
  551.         {  
  552.             return 0;  
  553.         }  
  554.   
  555.         assert(over_type);  
  556.   
  557.         switch(over_type->io_type)  
  558.         {  
  559.         case IO_EVENT_ACCEPT:  
  560.             {  
  561.                 acceptex_block* a_block = (acceptex_block*)over_type;  
  562.   
  563.                 if(close_socket)  
  564.                 {  
  565.                     on_tcp_listen_close(a_block);  
  566.                 }  
  567.                 else  
  568.                 {  
  569.                     on_acceptex(a_block);  
  570.                 }  
  571.             }  
  572.             break;  
  573.   
  574.         case IO_EVENT_WSARECV:  
  575.             {  
  576.                 recv_block* r_block = (recv_block*)over_type;  
  577.                 //连接断开  
  578.                 if (close_socket || bytes == 0 || bytes == -1)  
  579.                 {  
  580.                     //测试一下,确定对方肯定关闭连接了  
  581.                     char test_close;  
  582.                     int r = recv(r_block->socket, &test_close, sizeof(test_close), MSG_PEEK);  
  583.                     if(r == 0 || r == -1)  
  584.                     {  
  585.                         on_tcp_close(r_block);  
  586.                     }  
  587.                 }  
  588.                 //收到了bytes字节的数据  
  589.                 else  
  590.                 {  
  591.                     //处理数据  
  592.                     r_block->bytes_recveived = bytes;  
  593.                     on_recv(r_block);  
  594.                 }  
  595.             }  
  596.             break;  
  597.   
  598.   
  599.         case IO_EVENT_WSARECVFROM:  
  600.             {  
  601.                 recvfrom_block* rf_block = (recvfrom_block*)over_type;  
  602.   
  603.                 if(close_socket || bytes == -1 || bytes == 0)  
  604.                 {  
  605.                     on_udp_close(rf_block);  
  606.                 }  
  607.                 else  
  608.                 {  
  609.                     //处理数据  
  610.                     rf_block->bytes_recveived = bytes;  
  611.                     on_recvfrom(rf_block);  
  612.                 }  
  613.             }  
  614.             break;  
  615.   
  616.   
  617.         default:  
  618.             break;  
  619.         }  
  620.     }  
  621.     return 0;  


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445114.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PaperNotes(3)-图像分割-RCNN-FCN-Boxsup

图像分割算法对比小结1.{基本概念}2.{R-CNN}2.1R-CNN 网络结构选择性搜索算法为什么选择SVM作分类器边框回归2.2{R-CNN 训练}2.3{R-CNN实验结果}2.4{R-CNN语义分割}2.5{补充材料}2.5.1{R-CNN建议区域放缩}2.5.2{IOU阈值设置不一样的原因}2.5.3{Bounding-box回归修正}2.6{R-CNN存…

Python模块(3)--PIL 简易使用教程

PIL模块-用与记1.图片导入Image.open()2.图像显示.show()4.查看图片属性.format,.size,.mode3.图像格式转换.convert()4.图像模式“L”&#xff0c;“RGB”,"CYMK"5. 图片旋转.rotate()旋转方式1&#xff1a;旋转不扩展旋转方式2&#xff1a;旋转扩展旋转方式3&#…

日志级别 debug info warn eirror fatal

日志级别 debug info warn eirror fatal 软件中总免不了要使用诸如 Log4net, Log4j, Tracer 等东东来写日志&#xff0c;不管用什么&#xff0c;这些东东大多是大同小异的&#xff0c;一般都提供了这样5个日志级别&#xff1a; Debug Info Warn Error Fatal一个等级比一个高&…

输入输出系统

I/O设备&#xff1a;输入输出和存储功能的设备 I/O设备的分类 按传输的速度&#xff1a; 低速设备&#xff08;如键盘、鼠标、语音输入输出设备&#xff09; 中速设备&#xff08;如行式打印机、激光打印机等&#xff09; 高速设备&#xff08;如磁带机、磁盘机、光盘机等&…

vue2源码解析---v-model双向数据绑定

什么是v-model v-model 是 Vue 中的一个指令&#xff0c;用于实现表单元素与 Vue 实例中数据的双向绑定。这意味着当表单元素的值发生变化时&#xff0c;Vue 实例中的数据也会随之更新 工作原理 生成ast树 本质上是语法糖 结合了v-bind和v-on两个指令 示例代码 new Vue({e…

php收集的精典代码

1. οncοntextmenu"window.event.return&#xff06;#118aluefalse" 将彻底屏蔽鼠标右键 <table border οncοntextmenureturn(false)><td>no</table> 可用于Table 2. <body onselectstart"return false"> 取消选取、防止复制…

python外卷(7)--glob

glob模块1.glob.glob()2.对比os.listdir()glob是python自带的一个操作文件的模块&#xff0c;可用于查找 指定路径 中 匹配的 文件。1.glob.glob() 下面是一个测试文件路径&#xff1a; (base) pppp-System-Product-Name:~/Desktop/test_glob$ tree . ├── a │ ├── 1…

Sublime Text 2配置强大的IDE开发环境,运行java

Sublime Text 2是我无意中发现的、据说十分强大的、便捷的编辑器&#xff0c;许多程序员都投入到Sublime Text 2的怀抱中。 1 配置java开发环境的方法如下&#xff1a; 在jdk安装目录下的bin文件夹下新建一个bat格式的文件&#xff0c;文件命为javacexec.bat。 如果是在Wind…

thinkphp的快捷方法实例化对象

D、F、S、C、L、A、I 他们都在functions.php这个文件家 下面我分别说明一下他们的功能 D&#xff08;&#xff09; 加载Model类 M&#xff08;&#xff09; 加载Model类 A&#xff08;&#xff09; 加载Action类 L&#xff08;&#xff09; 获取语言定义 C&#xff08;&#xf…

Python外卷(8)--pdist, squareform

pdist, squareform1.pdist, squareform使用例子2.通过矩阵的四则运算实现上述pdist, squareformscipy.spatial.distance 距离计算库中有两个函数&#xff1a;pdist, squareform&#xff0c;用于计算样本对之间的欧式距离&#xff0c;并且将样本间距离用方阵表示出来。&#xff…

模拟进程调度

功能 data.h #ifndef _Data_h_ #define _Data_h_#include <stdio.h> #include <stdlib.h> #include <string.h>#define ElemType PCB #define Status int #define OK 1 #define ERROR 0 #define TimeSlice 1 #define Infinity 10 //INT_MAX#define NAME_M…

gdb调试多进程和多线程命令

1. 默认设置下&#xff0c;在调试多进程程序时GDB只会调试主进程。但是GDB&#xff08;>V7.0&#xff09;支持多进程的 分别以及同时 调试&#xff0c;换句话说&#xff0c;GDB可以同时调试多个程序。只需要设置follow-fork-mode(默认值&#xff1a;parent)和detach-on-fork…

python外卷(10)--取整

"取整"那些事1.python 内置函数1.1int()--向下取整1.2round()--四舍五入2.math模块取整函数2.1 math.floor()--向下取整2.2 math.ceil()--向上取整2.3 math.modf()--分别取小数部分和整数部分3.numpy模块取整函数3.1 numpy.floor()--向下取整3.2 numpy.ceil()--向上取…

模拟银行家算法

介绍 data.h #ifndef _Data_h_ #define _Data_h_#include <stdio.h> #include <stdlib.h> #include <string.h>#define ElemType PCB #define Status int #define true 1 #define false 0 #define OK 1 #define ERROR 0 #define RESOURCE_NUM …

Lua 与 C混合编程 .

本文通过程序实例说明C调用lua脚本和lua调用C的方法: 先建立一个 test.c文件: #include <stdio.h> #include <stdlib.h> #include "lua.h" #include "lualib.h" #include "lauxlib.h" #pragma comment(lib, "lua5.1.lib&qu…

模拟固定分区分配

介绍 data.h #ifndef _Data_h_ #define _Data_h_#include <stdio.h> #include <stdlib.h> #include <string.h> #define LIST_INIT_SIZE 10 #define LISTINCREMENT 2 #define true 1 #define false 0 #define PCBType PCB #define Status int…

Linux下的lua和boost c++的搭建和安装

先下载lua &#xff0c;boost c http://www.lua.org/versions.html#5.2 http://www.boost.org/ http://sourceforge.net/projects/luabind/ 1. 安装lua [rootlocalhost ~]#tar zxvf lua-5.1.2.tar.gz -C /usr/local [rootlocalhost ~]# cd /usr/local/ [rootlocalhost lo…

模拟基本分页存储

介绍 data.h #ifndef _Data_h_ #define _Data_h_#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h>#define LIST_INIT_SIZE 10 #define LISTINCREMENT 2 #define true 1 #define false 0 #define PCBType PC…

常用正则表达式和shell命令列表

取当前目录下普通文件的后缀名列表&#xff1a; ls -l | awk /^-/{print $NF} |awk -F. {print $NF}|awk !/^$/ 匹配0和正整数的正则表达式&#xff08;除0以外&#xff0c;其它数字不能以0开头&#xff09;&#xff1a; (^0$)|(^[0-9]\d*$) 匹配中文字符的正则表达式&#xff…

无限踩坑系列(7)-Latex使用Tips

Latex常用命令1.latex注释2.图片左边对齐3.字母头上加声调4.脚注5.公式中加空格6.字体加粗体7.公式换行8.\textsuperscript{*}9.\begin{itemize}10.\operatorname{trace}11.\noindent12.\textcircled{}圆圈数字一些TIPs1.latex注释 单行使用百分号%注释 多行使用如下命令,在编…