Last active
December 15, 2015 12:38
-
-
Save castaneai/5261327 to your computer and use it in GitHub Desktop.
Winsockで簡易サーバー
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
コールバック関数を持つサーバーを作れるサンプル | |
*/ | |
#pragma comment(lib, "ws2_32.lib") | |
#include <WinSock2.h> | |
#include <list> | |
typedef void (*ONRECV)(const SOCKET socket, const char* data, const int data_length); | |
typedef void (*ONERROR)(const char* message, const int error_code); | |
void run_server(const char* ip_address, const unsigned short port, ONRECV on_recv, ONERROR on_error) | |
{ | |
// winsock 初期化 | |
WSADATA d; | |
WSAStartup(MAKEWORD(2, 0), &d); | |
// サーバー用ソケット作成 | |
SOCKET server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | |
sockaddr_in server_address; | |
server_address.sin_family = AF_INET; | |
server_address.sin_addr.S_un.S_addr = inet_addr(ip_address); | |
server_address.sin_port = htons(port); | |
if (bind(server_socket, (sockaddr*)&server_address, sizeof(server_address)) != 0) { | |
on_error("socket bind failed", GetLastError()); | |
return; | |
} | |
if (listen(server_socket, 5) != 0) { | |
on_error("socket listen failed", GetLastError()); | |
} | |
// ノンブロッキングにする | |
u_long socket_mode = 1; | |
ioctlsocket(server_socket, FIONBIO, &socket_mode); | |
// クライアントリスト | |
std::list<SOCKET> clients; | |
while (true) { | |
// 新しいクライアントの受け入れ | |
sockaddr_in client_address = {0}; | |
int client_address_length = sizeof(client_address); | |
SOCKET client = accept(server_socket, (sockaddr*)&client_address, &client_address_length); | |
if (client != INVALID_SOCKET) { | |
clients.push_back(client); | |
} | |
// 接続済のクライアントからの受信 | |
for (SOCKET client : clients) { | |
char buffer[0xffff] = {0}; | |
int received_length = recv(client, buffer, 0xffff, 0); | |
if (received_length < 1 && GetLastError() != WSAEWOULDBLOCK) { | |
clients.remove(client); | |
break; | |
} | |
if (received_length > 0) { | |
on_recv(client, buffer, received_length); | |
} | |
} | |
Sleep(10); | |
} | |
WSACleanup(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment