1、服务器
#pragma once
#include <Windows.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#define LISTEN_PORT 5000
#define BUFFER_SIZE 1024
unsigned 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 address
sockaddr_in local_addr;
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(LISTEN_PORT);
local_addr.sin_addr.s_addr = INADDR_ANY;
//bind
rc = 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;
}
//listen
rc = listen(sock_listen, 5);
if(SOCKET_ERROR == rc){
printf("error:listen failed!\n");
closesocket(sock_listen);
WSACleanup();
return -4;
}
//while circle
int 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 for
rc = 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
// WSAGetOverlappedResult
DWORD 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 client
int 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);
}//while
closesocket(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_in server_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_event
WSAEVENT 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 socket
server_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 wsasocket
sock_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;
}
//connect
if (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 head
MessageHead 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_buffer
char *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;
}
//recv
ZeroMemory(&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;
}
}
//WaitForMultipleObjects
DWORD 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;
}
// WSAGetOverlappedResult
DWORD 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 response
if (_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;
}