Windows sockets网络开发-重叠IO模型

来源:互联网 发布:编程规范命名规则 编辑:程序博客网 时间:2024/04/29 13:06

1、服务器

#pragma once#include <Windows.h>#include <WinSock2.h>#pragma comment(lib, "ws2_32.lib")#define  LISTEN_PORT 5000#define  BUFFER_SIZE 1024unsigned long WINAPI client_handler(void* lparam);int overlapped_io_tcp_server_daemon(){WSADATA wsd;if(WSAStartup(MAKEWORD(2,2), &wsd) != 0){printf("error:WSAStartup failed!\n");return -1;}SOCKET sock_listen;int rc;int socket_type = SOCK_STREAM;int error_code;//create socket//sock_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);sock_listen = WSASocket(AF_INET, socket_type,0,NULL,0,WSA_FLAG_OVERLAPPED); if(INVALID_SOCKET == sock_listen){printf("error:socket failed!\n");WSACleanup();return -2;}//set socket addresssockaddr_in local_addr;local_addr.sin_family = AF_INET;local_addr.sin_port = htons(LISTEN_PORT);local_addr.sin_addr.s_addr = INADDR_ANY;//bindrc = bind(sock_listen, (struct sockaddr*)&local_addr, sizeof(sockaddr_in));if(SOCKET_ERROR == rc){printf("error:bind failed!\n");closesocket(sock_listen);WSACleanup();return -3;}//listenrc = listen(sock_listen, 5);if(SOCKET_ERROR == rc){printf("error:listen failed!\n");closesocket(sock_listen);WSACleanup();return -4;}//while circleint total_wsaevent = 0;bool is_runnning = true;while(is_runnning){sockaddr_in remote;int remote_len = sizeof(remote);//阻塞SOCKET sock_conn = accept(sock_listen, (struct sockaddr*)&remote, &remote_len);if(INVALID_SOCKET == sock_conn){error_code = WSAGetLastError();break;}//if(total_wsaevent > WSA_MAXIMUM_WAIT_EVENTS){//printf("more than WSA_MAXIMUM_WAIT_EVENTS(64)\n");//closesocket(sock_conn);//break;//}DWORD thread_id;CloseHandle(CreateThread(NULL, 0, client_handler, (LPVOID)sock_conn, 0, &thread_id));//++total_wsaevent;}closesocket(sock_listen);WSACleanup();return 0;}unsigned long WINAPI client_handler(void* lparam){SOCKET sock_conn = (SOCKET)lparam;char recv_buffer[BUFFER_SIZE] = {0};WSABUF wsa_buf;wsa_buf.buf = recv_buffer;wsa_buf.len = sizeof(recv_buffer);DWORD NoBR;DWORD flags=0;int error_code = -1;DWORD rc;WSAEVENT wsa_event = WSACreateEvent();WSAOVERLAPPED wsa_overlapped;ZeroMemory(&wsa_overlapped, sizeof(wsa_overlapped));wsa_overlapped.hEvent = wsa_event;HANDLE wait_event[1];wait_event[0] = wsa_event;while(1){ZeroMemory(&wsa_overlapped, sizeof(wsa_overlapped));wsa_overlapped.hEvent = wsa_event;int recv_len = WSARecv(sock_conn, &wsa_buf, 1,&NoBR ,&flags, &wsa_overlapped,NULL);if (SOCKET_ERROR == recv_len){error_code = WSAGetLastError();if (WSA_IO_PENDING != error_code){closesocket(sock_conn);WSACloseEvent(wsa_event);return error_code;}}//wait forrc = WaitForMultipleObjects(1, wait_event, TRUE, INFINITE);if (WSA_WAIT_FAILED == rc || WSA_WAIT_TIMEOUT == rc){closesocket(sock_conn);WSACloseEvent(wsa_event);return rc;}else if (WAIT_OBJECT_0 + 1 == rc){//exit event;closesocket(sock_conn);WSACloseEvent(wsa_event);return rc;}//WAIT_OBJECT_0// WSAGetOverlappedResultDWORD transfered_len = 0;if (WSAGetOverlappedResult(sock_conn, &wsa_overlapped, &transfered_len, FALSE, &flags) == FALSE){error_code = WSAGetLastError();closesocket(sock_conn);WSACloseEvent(wsa_event);return error_code;}if (transfered_len == 0) //peer closed{error_code = WSAGetLastError();closesocket(sock_conn);WSACloseEvent(wsa_event);return error_code;//continue;}//handle data from clientint ret = send(sock_conn, wsa_buf.buf, transfered_len, 0);if(SOCKET_ERROR == ret){printf("echo send failed!\n");closesocket(sock_conn);WSACloseEvent(wsa_event);return -1;}printf("echo client\n");WSAResetEvent(wsa_event);}//whileclosesocket(sock_conn);WSACloseEvent(wsa_event);return 0;}

2、客户端

#pragma once#include <Windows.h>#include <WinSock2.h>#include <vector>#include <iostream>#pragma comment(lib, "ws2_32.lib")#define  LISTEN_PORT 5000#define  BUFFER_SIZE 1024#define  MSG_HEAD_TAG  "C2SV"typedef struct st_MessageHead{char  msg_tag[4];DWORD option;DWORD content_length;}MessageHead,*PMessageHead;int overlapped_io_tcp_client_daemon(const std::string &server_ip, unsigned short server_port, const std::string& content_data){WSADATA wsd;if(WSAStartup(MAKEWORD(2,2),&wsd) !=0){printf("error:WSAStartup failed!\n");return -1;}int socket_type = SOCK_STREAM;sockaddr_inserver_sockaddr;SOCKET sock_conn;char recv_buffer[BUFFER_SIZE] = {0};WSABUF wsabuf;wsabuf.buf=recv_buffer;wsabuf.len=sizeof(recv_buffer);DWORD NoBR;DWORD flags=0;int error_code = -1;//create wsa_eventWSAEVENT wsa_event = WSACreateEvent();if (WSA_INVALID_EVENT == wsa_event){error_code = WSAGetLastError();WSACleanup();return error_code;}HANDLE hEvents[1];hEvents[0] = wsa_event;WSAOVERLAPPED wsa_overlappped;ZeroMemory(&wsa_overlappped, sizeof(wsa_overlappped));wsa_overlappped.hEvent = wsa_event;//start up socketserver_sockaddr.sin_addr.s_addr = inet_addr(server_ip.c_str());   server_sockaddr.sin_family = AF_INET;server_sockaddr.sin_port = htons(server_port);////startup wsasocketsock_conn = WSASocket(AF_INET, socket_type,0, NULL, 0, WSA_FLAG_OVERLAPPED );if (INVALID_SOCKET == sock_conn){error_code = WSAGetLastError();WSACloseEvent(wsa_event);WSACleanup();return error_code;}//connectif (connect(sock_conn,(SOCKADDR*)&server_sockaddr,sizeof(server_sockaddr)) == SOCKET_ERROR){error_code = WSAGetLastError();closesocket(sock_conn);WSACloseEvent(wsa_event);WSACleanup();return error_code;}//客户端不停地向服务器发送测试数据while (1){//construct message headMessageHead msg_head;memcpy(msg_head.msg_tag, MSG_HEAD_TAG, 4);msg_head.option = 0;msg_head.content_length = (DWORD)content_data.size();//total length int total_send_length = (int) (sizeof(MessageHead) + content_data.size());std::vector<char> send_buffer;send_buffer.reserve(total_send_length);send_buffer.assign(total_send_length, 0);//fill send_bufferchar *postion = &send_buffer[0];memcpy(postion, &msg_head, sizeof(msg_head));memcpy(postion + sizeof(msg_head), content_data.c_str(), content_data.size());int left_len = total_send_length;int sent_len = 0;while(left_len > 0){sent_len = send(sock_conn, postion, left_len, 0);if (SOCKET_ERROR == sent_len){error_code = WSAGetLastError();closesocket(sock_conn);WSACloseEvent(wsa_event);WSACleanup();return error_code;}left_len = total_send_length - sent_len;postion+=sent_len;}//recvZeroMemory(&wsa_overlappped, sizeof(wsa_overlappped));wsa_overlappped.hEvent = wsa_event;int recv_len = WSARecv(sock_conn, &wsabuf, 1,&NoBR ,&flags, &wsa_overlappped,NULL);if (SOCKET_ERROR == recv_len){error_code = WSAGetLastError();if (WSA_IO_PENDING != error_code){closesocket(sock_conn);WSACloseEvent(wsa_event);WSACleanup();return error_code;}}//WaitForMultipleObjectsDWORD rc = WaitForMultipleObjects(1,hEvents, FALSE, 15*1000 );if (WSA_WAIT_FAILED == rc || WSA_WAIT_TIMEOUT == rc){closesocket(sock_conn);WSACloseEvent(wsa_event);WSACleanup();return rc;}else if (WAIT_OBJECT_0 + 1 == rc){//exit event;closesocket(sock_conn);WSACloseEvent(wsa_event);WSACleanup();return rc;}// WSAGetOverlappedResultDWORD transfered_len = 0;if (WSAGetOverlappedResult(sock_conn, &wsa_overlappped, &transfered_len, FALSE, &flags) == FALSE){error_code = WSAGetLastError();closesocket(sock_conn);WSACloseEvent(wsa_event);WSACleanup();return error_code;}//closesocket(sock_conn);//WSACloseEvent(wsa_event);if (transfered_len == 0) //peer closed{error_code = WSAGetLastError();WSACleanup();return error_code;}//recv responseif (_strnicmp(recv_buffer,MSG_HEAD_TAG,strlen(MSG_HEAD_TAG))==0){MessageHead *msg_head = (MessageHead*)recv_buffer;const char  *recv_content_ptr = recv_buffer + sizeof(MessageHead);std::string recv_content_data(recv_content_ptr, msg_head->content_length);std::cout<<"recv from server:"<<recv_content_data.c_str()<<std::endl;}WSAResetEvent(wsa_event);Sleep(1000);}closesocket(sock_conn);WSACloseEvent(wsa_event);WSACleanup();return 0;}


0 0
原创粉丝点击