C++/ソケットサンプル2(Windowsサーバ・クライアント)
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
''[[FrontPage]]''
* C++/ソケットサンプル2(Windowsサーバ・クライアント) [#e8...
Windows上でサーバ及びクライアントとして動作するサンプルを...
引数1に(1: クライアント、2: サーバ、3: 両方)を指定。~
引数2に接続先ホスト名を指定。~
[[C++/ソケットサンプル1(Linuxサーバ)]]~
[[Java/ソケットサンプル]]
** 制約 [#k448f33e]
サンプルとして、ホスト名"clove.la"でアクセスできること。~
サンプルとして、ポート"57891"でアクセスできること。~
コンパイルのコマンドラインは"cl.exe seqSv.cpp"
~
~
ファイル名: seqSv.cpp
#include <stdio.h> ...
#include <time.h> ...
//#include <tchar.h> ...
...
//#define WIN32 ...
#define ARG_NUM 2 ...
#define MAX_SESSIONS 2 ...
#define RET_OK 0 ...
#define RET_NG (-1) ...
#define IND_TRUE 10 ...
#define IND_FALSE 0 ...
#define SV_PORT 57891 ...
#define ZERO 0 ...
#define SOCK_TIMER 5 ...
#define DEF_BUFF_LEN 1200 ...
...
#ifdef WIN32 ...
//#include <windows.h> ...
#include <winsock2.h> ...
#include <process.h> ...
#pragma once ...
#pragma comment(lib,"ws2_32.lib") ...
#else ...
#include <unistd.h> ...
#include <sys/socket.h> ...
#include <arpa/inet.h> ...
#include <netdb.h> ...
#endif ...
...
unsigned long vc_svAddr; ...
...
/* Class Multi Thread **********************************...
class cl_mt ...
{ ...
private: ...
...
protected: ...
HANDLE vc_handle; ...
HANDLE vc_events[2]; ...
unsigned int vc_threadId; ...
int vc_kill_threads; ...
...
public: ...
cl_mt(); ...
~cl_mt(); ...
...
char init( void ); ...
virtual char create_thread( void ){ return( RET_OK )...
char destroyThreads( void ); ...
}; ...
//*Class Multi Thread **********************************...
/* Class Server ****************************************...
class cl_server : public cl_mt ...
{ ...
private: ...
SOCKET vc_sv_sessions[MAX_SESSIONS + 1]; ...
int vc_sv_sessionId; ...
...
public: ...
cl_server(); ...
~cl_server(); ...
...
virtual char create_thread( void ); ...
unsigned int static __stdcall th_receiver( void* ); ...
...
char addFd( SOCKET vd_sock, fd_set* vd_fds ) ...
{ ...
#pragma warning( disable:4127 ) ...
FD_SET( vd_sock, vd_fds ); ...
#pragma warning( default:4127 ) ...
return( RET_OK ); ...
} ...
...
char delFd( SOCKET vd_sock, fd_set* vd_fds ) ...
{ ...
#pragma warning( disable:4127 ) ...
FD_CLR( vd_sock, vd_fds ); ...
#pragma warning( default:4127 ) ...
return( RET_OK ); ...
} ...
}; ...
...
cl_server obj_server; ...
//extern cl_server obj_server; ...
//*Class Server ****************************************...
/* Class Client ****************************************...
class cl_client : public cl_mt ...
{ ...
private: ...
...
public: ...
cl_client(); ...
~cl_client(); ...
...
virtual char create_thread( void ); ...
unsigned int static __stdcall th_receiver( void* ); ...
}; ...
...
cl_client obj_client; ...
//extern cl_client obj_client; ...
//*Class Client ****************************************...
/* Main ************************************************...
char main( int argc, char **argv ) ...
{ ...
clock_t start, end; ...
start = clock(); ...
...
char rtnCod = RET_OK; ...
int mode; ...
HOSTENT *host; ...
int index = RET_OK; ...
WSADATA wsadata; ...
...
for( ; ; ) ...
{ ...
if( ARG_NUM >= argc ) ...
{ ...
rtnCod = RET_NG; ...
printf( "argments required.\n\n" ); ...
break; ...
} ...
...
mode = atoi(argv[1]); ...
if( 1 > mode ) ...
{ ...
rtnCod = RET_NG; ...
printf( "mode: \n1 - client only.\n2 - serve...
break; ...
} ...
...
index = WSAStartup( MAKEWORD(2, 2), &wsadata ); ...
if( RET_OK != index ) ...
{ ...
printf( "WSAStartup failed.\n" ); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
vc_svAddr = inet_addr( argv[2] ); ...
if( RET_NG == vc_svAddr ) ...
{ ...
host = gethostbyname( argv[2] ); ...
if( NULL != host ) ...
{ ...
vc_svAddr = *((unsigned long *)(host->h_...
} ...
else ...
{ ...
printf( "invalid addr or hostname.\n" );...
printf( "error: %d\n", WSAGetLastError()...
rtnCod = RET_NG; ...
break; ...
} ...
} ...
...
if( 2 == (2 & mode) ) ...
{ ...
obj_server.init(); ...
} ...
...
if( 1 == (1 & mode) ) ...
{ ...
obj_client.init(); ...
} ...
...
end = clock(); ...
printf( "it takes %d msec.\n\n", end - start ); ...
getchar(); ...
...
if( 1 == (1 & mode) ) ...
{ ...
obj_client.destroyThreads(); ...
} ...
...
if( 2 == (2 & mode) ) ...
{ ...
obj_server.destroyThreads(); ...
Sleep( 5000 ); ...
} ...
...
getchar(); ...
...
if( SOCKET_ERROR == WSACleanup() ) ...
{ ...
printf( "failed to WSACleanup().\n\n" ); ...
rtnCod = RET_NG; ...
} ...
...
break; ...
} ...
...
return( RET_OK ); ...
} ...
//*Main ************************************************...
/* Server Receiver Thread ******************************...
unsigned int __stdcall cl_server::th_receiver( void* ) ...
{ ...
char rtnCod = RET_OK; ...
int errInd; ...
int clAddrLen; ...
int index = RET_OK; ...
...
struct sockaddr_in svAddr; ...
struct sockaddr_in clAddr; ...
IN_ADDR clInAddr; ...
...
SOCKET sock = NULL; ...
SOCKET clSock = NULL; ...
char bufStr[DEF_BUFF_LEN] = ""; ...
int recvBytes; ...
int sessionNum = ZERO; ...
int sessionIndicator; ...
int cnt; ...
int firstInd = IND_TRUE; ...
struct timeval tmVal = { SOCK_TIMER, ZERO }; ...
fd_set readFd = { ZERO, }; ...
fd_set initFd = { ZERO, }; ...
...
FD_ZERO( &initFd ); ...
...
for( ; ; ) ...
{ ...
// printf( "This is server's thread.\n\n" ); ...
WaitForSingleObject( obj_server.vc_events[1], IN...
// ResetEvent( obj_server.vc_events[1] ); ...
printf( "This is server's thread.\n\n" ); ...
...
if( IND_TRUE == obj_server.vc_kill_threads ) ...
{ ...
for( cnt = ZERO; MAX_SESSIONS > cnt; cnt++ )...
{ ...
if( NULL != obj_server.vc_sv_sessions[cn...
{ ...
send( clSock, "closed by network.\n\...
shutdown( clSock, 2 ); ...
closesocket( clSock ); ...
} ...
} ...
...
printf( "Server's thread killed.\n\n" ); ...
break; ...
} ...
...
if( IND_TRUE == firstInd ) ...
{ ...
firstInd = IND_FALSE; ...
sock = socket( AF_INET, SOCK_STREAM, 0 ); ...
if( INVALID_SOCKET == sock ) ...
{ ...
printf("failed to generate socket.\n"); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
memset( &svAddr, 0, sizeof(IN_ADDR) ); ...
svAddr.sin_family = AF_INET; ...
svAddr.sin_port = htons( SV_PORT ); ...
svAddr.sin_addr.S_un.S_addr = INADDR_ANY; ...
...
index = bind( sock, (struct sockaddr *)&svAd...
if( SOCKET_ERROR == index ) ...
{ ...
printf("failed to bind socket.\n"); ...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
index = listen( sock, MAX_SESSIONS + 1 ); ...
if( SOCKET_ERROR != index ) ...
{ ...
printf("waiting for clients.\n\n"); ...
clAddrLen = sizeof(clAddr); ...
} ...
else ...
{ ...
printf("failed to listen socket.\n"); ...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
obj_server.addFd( sock, &initFd ); ...
} ...
...
for( ; ; ) ...
{ ...
memcpy( &readFd, &initFd, sizeof(fd_set) ); ...
if( IND_TRUE == obj_server.vc_kill_threads )...
{ ...
break; ...
} ...
...
index = select( 0, &readFd, NULL, NULL, &tmV...
if( FD_ISSET( sock, &readFd) ) ...
{ ...
clSock = accept( sock, (LPSOCKADDR)&clAd...
if( INVALID_SOCKET != clSock ) ...
{ ...
memcpy( &clInAddr, &clAddr.sin_addr....
printf( "a client accepted: %s\n\n",...
...
if( MAX_SESSIONS == sessionNum ) ...
{ ...
printf( "session full.\n\n" ); ...
_snprintf_s( bufStr, sizeof(bufS...
send( clSock, bufStr, strlen(buf...
shutdown( clSock, 2 ); ...
closesocket( clSock ); ...
continue; ...
} ...
...
for( sessionIndicator = ZERO; ...
MAX_SESSIONS > sessionIndicator...
{ ...
if( NULL == obj_server.vc_sv_ses...
{ ...
obj_server.vc_sv_sessions[se...
printf( "session ID: %d\n\n"...
obj_server.addFd( clSock, &i...
sessionNum++; ...
printf( "sessions: %d\n\n", ...
break; ...
} ...
} ...
} ...
else ...
{ ...
printf( "failed to accept.\n" ); ...
printf( "error: %d\n", WSAGetLastErr...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
} ...
...
for( cnt = ZERO; MAX_SESSIONS > cnt; cnt++ )...
{ ...
if( FD_ISSET(obj_server.vc_sv_sessions[c...
{ ...
clSock = obj_server.vc_sv_sessions[c...
recvBytes = recv( clSock, bufStr, si...
printf( "recvBytes = %d.\n\n", recvB...
if( SOCKET_ERROR == recvBytes ) ...
{ ...
errInd = WSAGetLastError(); ...
if( WSAECONNRESET == errInd ) ...
{ ...
printf( "session closed.\n\n...
} ...
else ...
{ ...
printf( "failed to receive.\...
printf( "error: %d\n", errIn...
} ...
obj_server.delFd( clSock, &initF...
obj_server.vc_sv_sessions[cnt] =...
closesocket( clSock ); ...
sessionNum--; ...
continue; ...
} ...
else if( ZERO == recvBytes ) ...
{ ...
printf( "session closed.\n\n" );...
obj_server.delFd( clSock, &initF...
obj_server.vc_sv_sessions[cnt] =...
closesocket( clSock ); ...
sessionNum--; ...
continue; ...
} ...
bufStr[recvBytes] = '\0'; ...
printf( "server rec: %s\n", bufStr )...
...
index = send( clSock, bufStr, strlen...
if( SOCKET_ERROR == index ) ...
{ ...
printf( "failed to send.\n" ); ...
printf( "error: %d\n", WSAGetLas...
obj_server.delFd( clSock, &initF...
obj_server.vc_sv_sessions[cnt] =...
shutdown( clSock, 2 ); ...
closesocket( clSock ); ...
sessionNum--; ...
rtnCod = RET_NG; ...
continue; ...
} ...
} ...
} ...
printf( "go next selection.\n\n" ); ...
} ...
} ...
...
shutdown( sock, 2 ); ...
shutdown( clSock, 2 ); ...
closesocket( sock ); ...
closesocket( clSock ); ...
...
_endthreadex( rtnCod ); ...
return( rtnCod ); ...
} ...
//*Server Thread ***************************************...
/* Client Receiver Thread ******************************...
unsigned int __stdcall cl_client::th_receiver( void* ) ...
{ ...
char rtnCod = RET_OK; ...
int index = RET_OK; ...
SOCKET sock = NULL; ...
unsigned long svAddr = vc_svAddr; ...
SOCKADDR_IN svAddrInfo; ...
char msg[DEF_BUFF_LEN] = ""; ...
int recvBytes; ...
...
for( ; ; ) ...
{ ...
WaitForSingleObject( obj_client.vc_events[1], IN...
ResetEvent( obj_client.vc_events[1] ); ...
printf( "This is client's thread.\n\n" ); ...
...
if( IND_TRUE == obj_client.vc_kill_threads ) ...
{ ...
printf( "Client's thread killed.\n\n" ); ...
closesocket( sock ); ...
break; ...
} ...
...
sock = socket( AF_INET, SOCK_STREAM, 0 ); ...
if( INVALID_SOCKET == sock ) ...
{ ...
printf("failed to generate socket.\n"); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
svAddrInfo.sin_family = AF_INET; ...
svAddrInfo.sin_addr.s_addr = svAddr; ...
svAddrInfo.sin_port = htons( (unsigned short)SV_...
...
index = connect( sock, (LPSOCKADDR)&svAddrInfo, ...
if( SOCKET_ERROR == index ) ...
{ ...
printf( "failed to connect.\n" ); ...
printf( "error: %d.\n", WSAGetLastError() );...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
_snprintf_s( msg, sizeof(msg), 8, "%s", "Hello.\...
index = send( sock, msg, strlen(msg), 0 ); ...
if( SOCKET_ERROR == index ) ...
{ ...
printf( "failed to send.\n" ); ...
printf( "error: %d\n", WSAGetLastError() ); ...
shutdown( sock, 2 ); ...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
recvBytes = recv( sock, msg, sizeof(msg), 0 ); ...
if( SOCKET_ERROR == recvBytes ) ...
{ ...
printf( "failed to receive.\n" ); ...
printf( "error: %d\n", WSAGetLastError() ); ...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
printf( "recvBytes = %d.\n\n", recvBytes ); ...
msg[recvBytes] = '\0'; ...
printf( "client rec: %s\n", msg ); ...
} ...
...
shutdown( sock, 2 ); ...
closesocket( sock ); ...
...
_endthreadex( rtnCod ); ...
return( rtnCod ); ...
} ...
//*Client Receiver Thread ******************************...
/* Multi Thread Constructor ****************************...
cl_mt::cl_mt () ...
: vc_kill_threads( IND_FALSE ), ...
vc_threadId( NULL ) ...
{ ...
} ...
//*Multi Thread Constructor ****************************...
/* Multi Thread Initializer ****************************...
char cl_mt::init( void ) ...
{ ...
char rtnCod = RET_OK; ...
...
for ( ; ; ) ...
{ ...
create_thread(); ...
SetEvent( vc_events[1] ); ...
...
break; ...
} ...
...
return( rtnCod ); ...
} ...
//*Multi Thread Initializer ****************************...
/* Destroy Threads *************************************...
char cl_mt::destroyThreads( void ) ...
{ ...
char rtnCod = RET_OK; ...
...
vc_kill_threads = IND_TRUE; ...
SetEvent( vc_events[1] ); ...
Sleep( 25 ); ...
CloseHandle( vc_handle ); ...
...
return( rtnCod ); ...
} ...
//*Destroy Server's Threads ****************************...
/* Multi Thread Deconstructor **************************...
cl_mt::~cl_mt () ...
{ ...
CloseHandle( vc_events[0] ); ...
CloseHandle( vc_events[1] ); ...
} ...
//*Multi Thread Deconstructor **************************...
/* Client Constructor **********************************...
cl_client::cl_client () ...
{ ...
int vn_pid = GetCurrentProcessId(); ...
// TCHAR eventName[16]; ...
char eventName[16]; ...
...
printf( "vn_pid = %d\n\n", vn_pid ); ...
_sntprintf_s( eventName, _countof(eventName), 16, _T...
...
vc_events[0] = CreateEvent( NULL, ...
TRUE, ...
FALSE, ...
_T("TH_CL") ); ...
vc_events[1] = CreateEvent( NULL, TRUE, FALSE, event...
} ...
//*Client Constructor **********************************...
/* Client Deconstructor ********************************...
cl_client::~cl_client () ...
{ ...
} ...
//*Client Deconstructor ********************************...
/* Server Constructor **********************************...
cl_server::cl_server () ...
: vc_sv_sessionId( ZERO ) ...
{ ...
int cnt = ZERO; ...
...
for( ; MAX_SESSIONS + 1 > cnt; cnt++ ) ...
{ ...
vc_sv_sessions[cnt] = NULL; ...
} ...
...
vc_events[0] = CreateEvent( NULL, ...
TRUE, ...
FALSE, ...
_T("TH_SV") ); ...
vc_events[1] = CreateEvent( NULL, TRUE, FALSE, _T("R...
} ...
//*Server Constructor **********************************...
/* Server Deconstructor ********************************...
cl_server::~cl_server () ...
{ ...
} ...
//*Server Deconstructor ********************************...
/* Create Client Thread ********************************...
char cl_client::create_thread( void ) ...
{ ...
char rtnCod = RET_OK; ...
...
for( ; ; ) ...
{ ...
if( NULL != vc_threadId ) ...
{ ...
SetEvent( vc_events[1] ); ...
} ...
else ...
{ ...
vc_handle = ...
(HANDLE)_beginthreadex( NULL, ...
RET_OK, ...
&cl_client::th_r...
NULL, ...
RET_OK, ...
&(vc_threadId) )...
} ...
...
break; ...
} ...
...
return( rtnCod ); ...
} ...
//*Create Client Thread ********************************...
/* Create Server Thread ********************************...
char cl_server::create_thread( void ) ...
{ ...
char rtnCod = RET_OK; ...
...
for( ; ; ) ...
{ ...
if( NULL != vc_threadId ) ...
{ ...
SetEvent( vc_events[1] ); ...
} ...
else ...
{ ...
vc_handle = ...
(HANDLE)_beginthreadex( NULL, ...
RET_OK, ...
&cl_server::th_r...
NULL, ...
RET_OK, ...
&(vc_threadId) )...
} ...
...
break; ...
} ...
...
return( rtnCod ); ...
} ...
//*Create Server Thread ********************************...
動作確認
>cl.exe seqSv.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15...
Copyright (C) Microsoft Corporation. All rights reserved.
seqSv.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:seqSv.exe
seqSv.obj
>seqSv.exe 3 localhost
vn_pid = 5564
it takes 16 msec.
This is client's thread.
This is server's thread.
waiting for clients.
a client accepted: 127.0.0.1
session ID: 0
sessions: 1
go next selection.
recvBytes = 7.
server rec: Hello.
go next selection.
recvBytes = 7.
client rec: Hello.
This is client's thread.
Client's thread killed.
recvBytes = 0.
session closed.
go next selection.
go next selection.
This is server's thread.
Server's thread killed.
>
*** 修正履歴 [#ua9ab7c0]
~
*** 課題 [#wae2c1e5]
~
終了行:
''[[FrontPage]]''
* C++/ソケットサンプル2(Windowsサーバ・クライアント) [#e8...
Windows上でサーバ及びクライアントとして動作するサンプルを...
引数1に(1: クライアント、2: サーバ、3: 両方)を指定。~
引数2に接続先ホスト名を指定。~
[[C++/ソケットサンプル1(Linuxサーバ)]]~
[[Java/ソケットサンプル]]
** 制約 [#k448f33e]
サンプルとして、ホスト名"clove.la"でアクセスできること。~
サンプルとして、ポート"57891"でアクセスできること。~
コンパイルのコマンドラインは"cl.exe seqSv.cpp"
~
~
ファイル名: seqSv.cpp
#include <stdio.h> ...
#include <time.h> ...
//#include <tchar.h> ...
...
//#define WIN32 ...
#define ARG_NUM 2 ...
#define MAX_SESSIONS 2 ...
#define RET_OK 0 ...
#define RET_NG (-1) ...
#define IND_TRUE 10 ...
#define IND_FALSE 0 ...
#define SV_PORT 57891 ...
#define ZERO 0 ...
#define SOCK_TIMER 5 ...
#define DEF_BUFF_LEN 1200 ...
...
#ifdef WIN32 ...
//#include <windows.h> ...
#include <winsock2.h> ...
#include <process.h> ...
#pragma once ...
#pragma comment(lib,"ws2_32.lib") ...
#else ...
#include <unistd.h> ...
#include <sys/socket.h> ...
#include <arpa/inet.h> ...
#include <netdb.h> ...
#endif ...
...
unsigned long vc_svAddr; ...
...
/* Class Multi Thread **********************************...
class cl_mt ...
{ ...
private: ...
...
protected: ...
HANDLE vc_handle; ...
HANDLE vc_events[2]; ...
unsigned int vc_threadId; ...
int vc_kill_threads; ...
...
public: ...
cl_mt(); ...
~cl_mt(); ...
...
char init( void ); ...
virtual char create_thread( void ){ return( RET_OK )...
char destroyThreads( void ); ...
}; ...
//*Class Multi Thread **********************************...
/* Class Server ****************************************...
class cl_server : public cl_mt ...
{ ...
private: ...
SOCKET vc_sv_sessions[MAX_SESSIONS + 1]; ...
int vc_sv_sessionId; ...
...
public: ...
cl_server(); ...
~cl_server(); ...
...
virtual char create_thread( void ); ...
unsigned int static __stdcall th_receiver( void* ); ...
...
char addFd( SOCKET vd_sock, fd_set* vd_fds ) ...
{ ...
#pragma warning( disable:4127 ) ...
FD_SET( vd_sock, vd_fds ); ...
#pragma warning( default:4127 ) ...
return( RET_OK ); ...
} ...
...
char delFd( SOCKET vd_sock, fd_set* vd_fds ) ...
{ ...
#pragma warning( disable:4127 ) ...
FD_CLR( vd_sock, vd_fds ); ...
#pragma warning( default:4127 ) ...
return( RET_OK ); ...
} ...
}; ...
...
cl_server obj_server; ...
//extern cl_server obj_server; ...
//*Class Server ****************************************...
/* Class Client ****************************************...
class cl_client : public cl_mt ...
{ ...
private: ...
...
public: ...
cl_client(); ...
~cl_client(); ...
...
virtual char create_thread( void ); ...
unsigned int static __stdcall th_receiver( void* ); ...
}; ...
...
cl_client obj_client; ...
//extern cl_client obj_client; ...
//*Class Client ****************************************...
/* Main ************************************************...
char main( int argc, char **argv ) ...
{ ...
clock_t start, end; ...
start = clock(); ...
...
char rtnCod = RET_OK; ...
int mode; ...
HOSTENT *host; ...
int index = RET_OK; ...
WSADATA wsadata; ...
...
for( ; ; ) ...
{ ...
if( ARG_NUM >= argc ) ...
{ ...
rtnCod = RET_NG; ...
printf( "argments required.\n\n" ); ...
break; ...
} ...
...
mode = atoi(argv[1]); ...
if( 1 > mode ) ...
{ ...
rtnCod = RET_NG; ...
printf( "mode: \n1 - client only.\n2 - serve...
break; ...
} ...
...
index = WSAStartup( MAKEWORD(2, 2), &wsadata ); ...
if( RET_OK != index ) ...
{ ...
printf( "WSAStartup failed.\n" ); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
vc_svAddr = inet_addr( argv[2] ); ...
if( RET_NG == vc_svAddr ) ...
{ ...
host = gethostbyname( argv[2] ); ...
if( NULL != host ) ...
{ ...
vc_svAddr = *((unsigned long *)(host->h_...
} ...
else ...
{ ...
printf( "invalid addr or hostname.\n" );...
printf( "error: %d\n", WSAGetLastError()...
rtnCod = RET_NG; ...
break; ...
} ...
} ...
...
if( 2 == (2 & mode) ) ...
{ ...
obj_server.init(); ...
} ...
...
if( 1 == (1 & mode) ) ...
{ ...
obj_client.init(); ...
} ...
...
end = clock(); ...
printf( "it takes %d msec.\n\n", end - start ); ...
getchar(); ...
...
if( 1 == (1 & mode) ) ...
{ ...
obj_client.destroyThreads(); ...
} ...
...
if( 2 == (2 & mode) ) ...
{ ...
obj_server.destroyThreads(); ...
Sleep( 5000 ); ...
} ...
...
getchar(); ...
...
if( SOCKET_ERROR == WSACleanup() ) ...
{ ...
printf( "failed to WSACleanup().\n\n" ); ...
rtnCod = RET_NG; ...
} ...
...
break; ...
} ...
...
return( RET_OK ); ...
} ...
//*Main ************************************************...
/* Server Receiver Thread ******************************...
unsigned int __stdcall cl_server::th_receiver( void* ) ...
{ ...
char rtnCod = RET_OK; ...
int errInd; ...
int clAddrLen; ...
int index = RET_OK; ...
...
struct sockaddr_in svAddr; ...
struct sockaddr_in clAddr; ...
IN_ADDR clInAddr; ...
...
SOCKET sock = NULL; ...
SOCKET clSock = NULL; ...
char bufStr[DEF_BUFF_LEN] = ""; ...
int recvBytes; ...
int sessionNum = ZERO; ...
int sessionIndicator; ...
int cnt; ...
int firstInd = IND_TRUE; ...
struct timeval tmVal = { SOCK_TIMER, ZERO }; ...
fd_set readFd = { ZERO, }; ...
fd_set initFd = { ZERO, }; ...
...
FD_ZERO( &initFd ); ...
...
for( ; ; ) ...
{ ...
// printf( "This is server's thread.\n\n" ); ...
WaitForSingleObject( obj_server.vc_events[1], IN...
// ResetEvent( obj_server.vc_events[1] ); ...
printf( "This is server's thread.\n\n" ); ...
...
if( IND_TRUE == obj_server.vc_kill_threads ) ...
{ ...
for( cnt = ZERO; MAX_SESSIONS > cnt; cnt++ )...
{ ...
if( NULL != obj_server.vc_sv_sessions[cn...
{ ...
send( clSock, "closed by network.\n\...
shutdown( clSock, 2 ); ...
closesocket( clSock ); ...
} ...
} ...
...
printf( "Server's thread killed.\n\n" ); ...
break; ...
} ...
...
if( IND_TRUE == firstInd ) ...
{ ...
firstInd = IND_FALSE; ...
sock = socket( AF_INET, SOCK_STREAM, 0 ); ...
if( INVALID_SOCKET == sock ) ...
{ ...
printf("failed to generate socket.\n"); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
memset( &svAddr, 0, sizeof(IN_ADDR) ); ...
svAddr.sin_family = AF_INET; ...
svAddr.sin_port = htons( SV_PORT ); ...
svAddr.sin_addr.S_un.S_addr = INADDR_ANY; ...
...
index = bind( sock, (struct sockaddr *)&svAd...
if( SOCKET_ERROR == index ) ...
{ ...
printf("failed to bind socket.\n"); ...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
index = listen( sock, MAX_SESSIONS + 1 ); ...
if( SOCKET_ERROR != index ) ...
{ ...
printf("waiting for clients.\n\n"); ...
clAddrLen = sizeof(clAddr); ...
} ...
else ...
{ ...
printf("failed to listen socket.\n"); ...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
obj_server.addFd( sock, &initFd ); ...
} ...
...
for( ; ; ) ...
{ ...
memcpy( &readFd, &initFd, sizeof(fd_set) ); ...
if( IND_TRUE == obj_server.vc_kill_threads )...
{ ...
break; ...
} ...
...
index = select( 0, &readFd, NULL, NULL, &tmV...
if( FD_ISSET( sock, &readFd) ) ...
{ ...
clSock = accept( sock, (LPSOCKADDR)&clAd...
if( INVALID_SOCKET != clSock ) ...
{ ...
memcpy( &clInAddr, &clAddr.sin_addr....
printf( "a client accepted: %s\n\n",...
...
if( MAX_SESSIONS == sessionNum ) ...
{ ...
printf( "session full.\n\n" ); ...
_snprintf_s( bufStr, sizeof(bufS...
send( clSock, bufStr, strlen(buf...
shutdown( clSock, 2 ); ...
closesocket( clSock ); ...
continue; ...
} ...
...
for( sessionIndicator = ZERO; ...
MAX_SESSIONS > sessionIndicator...
{ ...
if( NULL == obj_server.vc_sv_ses...
{ ...
obj_server.vc_sv_sessions[se...
printf( "session ID: %d\n\n"...
obj_server.addFd( clSock, &i...
sessionNum++; ...
printf( "sessions: %d\n\n", ...
break; ...
} ...
} ...
} ...
else ...
{ ...
printf( "failed to accept.\n" ); ...
printf( "error: %d\n", WSAGetLastErr...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
} ...
...
for( cnt = ZERO; MAX_SESSIONS > cnt; cnt++ )...
{ ...
if( FD_ISSET(obj_server.vc_sv_sessions[c...
{ ...
clSock = obj_server.vc_sv_sessions[c...
recvBytes = recv( clSock, bufStr, si...
printf( "recvBytes = %d.\n\n", recvB...
if( SOCKET_ERROR == recvBytes ) ...
{ ...
errInd = WSAGetLastError(); ...
if( WSAECONNRESET == errInd ) ...
{ ...
printf( "session closed.\n\n...
} ...
else ...
{ ...
printf( "failed to receive.\...
printf( "error: %d\n", errIn...
} ...
obj_server.delFd( clSock, &initF...
obj_server.vc_sv_sessions[cnt] =...
closesocket( clSock ); ...
sessionNum--; ...
continue; ...
} ...
else if( ZERO == recvBytes ) ...
{ ...
printf( "session closed.\n\n" );...
obj_server.delFd( clSock, &initF...
obj_server.vc_sv_sessions[cnt] =...
closesocket( clSock ); ...
sessionNum--; ...
continue; ...
} ...
bufStr[recvBytes] = '\0'; ...
printf( "server rec: %s\n", bufStr )...
...
index = send( clSock, bufStr, strlen...
if( SOCKET_ERROR == index ) ...
{ ...
printf( "failed to send.\n" ); ...
printf( "error: %d\n", WSAGetLas...
obj_server.delFd( clSock, &initF...
obj_server.vc_sv_sessions[cnt] =...
shutdown( clSock, 2 ); ...
closesocket( clSock ); ...
sessionNum--; ...
rtnCod = RET_NG; ...
continue; ...
} ...
} ...
} ...
printf( "go next selection.\n\n" ); ...
} ...
} ...
...
shutdown( sock, 2 ); ...
shutdown( clSock, 2 ); ...
closesocket( sock ); ...
closesocket( clSock ); ...
...
_endthreadex( rtnCod ); ...
return( rtnCod ); ...
} ...
//*Server Thread ***************************************...
/* Client Receiver Thread ******************************...
unsigned int __stdcall cl_client::th_receiver( void* ) ...
{ ...
char rtnCod = RET_OK; ...
int index = RET_OK; ...
SOCKET sock = NULL; ...
unsigned long svAddr = vc_svAddr; ...
SOCKADDR_IN svAddrInfo; ...
char msg[DEF_BUFF_LEN] = ""; ...
int recvBytes; ...
...
for( ; ; ) ...
{ ...
WaitForSingleObject( obj_client.vc_events[1], IN...
ResetEvent( obj_client.vc_events[1] ); ...
printf( "This is client's thread.\n\n" ); ...
...
if( IND_TRUE == obj_client.vc_kill_threads ) ...
{ ...
printf( "Client's thread killed.\n\n" ); ...
closesocket( sock ); ...
break; ...
} ...
...
sock = socket( AF_INET, SOCK_STREAM, 0 ); ...
if( INVALID_SOCKET == sock ) ...
{ ...
printf("failed to generate socket.\n"); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
svAddrInfo.sin_family = AF_INET; ...
svAddrInfo.sin_addr.s_addr = svAddr; ...
svAddrInfo.sin_port = htons( (unsigned short)SV_...
...
index = connect( sock, (LPSOCKADDR)&svAddrInfo, ...
if( SOCKET_ERROR == index ) ...
{ ...
printf( "failed to connect.\n" ); ...
printf( "error: %d.\n", WSAGetLastError() );...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
_snprintf_s( msg, sizeof(msg), 8, "%s", "Hello.\...
index = send( sock, msg, strlen(msg), 0 ); ...
if( SOCKET_ERROR == index ) ...
{ ...
printf( "failed to send.\n" ); ...
printf( "error: %d\n", WSAGetLastError() ); ...
shutdown( sock, 2 ); ...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
...
recvBytes = recv( sock, msg, sizeof(msg), 0 ); ...
if( SOCKET_ERROR == recvBytes ) ...
{ ...
printf( "failed to receive.\n" ); ...
printf( "error: %d\n", WSAGetLastError() ); ...
closesocket( sock ); ...
rtnCod = RET_NG; ...
break; ...
} ...
printf( "recvBytes = %d.\n\n", recvBytes ); ...
msg[recvBytes] = '\0'; ...
printf( "client rec: %s\n", msg ); ...
} ...
...
shutdown( sock, 2 ); ...
closesocket( sock ); ...
...
_endthreadex( rtnCod ); ...
return( rtnCod ); ...
} ...
//*Client Receiver Thread ******************************...
/* Multi Thread Constructor ****************************...
cl_mt::cl_mt () ...
: vc_kill_threads( IND_FALSE ), ...
vc_threadId( NULL ) ...
{ ...
} ...
//*Multi Thread Constructor ****************************...
/* Multi Thread Initializer ****************************...
char cl_mt::init( void ) ...
{ ...
char rtnCod = RET_OK; ...
...
for ( ; ; ) ...
{ ...
create_thread(); ...
SetEvent( vc_events[1] ); ...
...
break; ...
} ...
...
return( rtnCod ); ...
} ...
//*Multi Thread Initializer ****************************...
/* Destroy Threads *************************************...
char cl_mt::destroyThreads( void ) ...
{ ...
char rtnCod = RET_OK; ...
...
vc_kill_threads = IND_TRUE; ...
SetEvent( vc_events[1] ); ...
Sleep( 25 ); ...
CloseHandle( vc_handle ); ...
...
return( rtnCod ); ...
} ...
//*Destroy Server's Threads ****************************...
/* Multi Thread Deconstructor **************************...
cl_mt::~cl_mt () ...
{ ...
CloseHandle( vc_events[0] ); ...
CloseHandle( vc_events[1] ); ...
} ...
//*Multi Thread Deconstructor **************************...
/* Client Constructor **********************************...
cl_client::cl_client () ...
{ ...
int vn_pid = GetCurrentProcessId(); ...
// TCHAR eventName[16]; ...
char eventName[16]; ...
...
printf( "vn_pid = %d\n\n", vn_pid ); ...
_sntprintf_s( eventName, _countof(eventName), 16, _T...
...
vc_events[0] = CreateEvent( NULL, ...
TRUE, ...
FALSE, ...
_T("TH_CL") ); ...
vc_events[1] = CreateEvent( NULL, TRUE, FALSE, event...
} ...
//*Client Constructor **********************************...
/* Client Deconstructor ********************************...
cl_client::~cl_client () ...
{ ...
} ...
//*Client Deconstructor ********************************...
/* Server Constructor **********************************...
cl_server::cl_server () ...
: vc_sv_sessionId( ZERO ) ...
{ ...
int cnt = ZERO; ...
...
for( ; MAX_SESSIONS + 1 > cnt; cnt++ ) ...
{ ...
vc_sv_sessions[cnt] = NULL; ...
} ...
...
vc_events[0] = CreateEvent( NULL, ...
TRUE, ...
FALSE, ...
_T("TH_SV") ); ...
vc_events[1] = CreateEvent( NULL, TRUE, FALSE, _T("R...
} ...
//*Server Constructor **********************************...
/* Server Deconstructor ********************************...
cl_server::~cl_server () ...
{ ...
} ...
//*Server Deconstructor ********************************...
/* Create Client Thread ********************************...
char cl_client::create_thread( void ) ...
{ ...
char rtnCod = RET_OK; ...
...
for( ; ; ) ...
{ ...
if( NULL != vc_threadId ) ...
{ ...
SetEvent( vc_events[1] ); ...
} ...
else ...
{ ...
vc_handle = ...
(HANDLE)_beginthreadex( NULL, ...
RET_OK, ...
&cl_client::th_r...
NULL, ...
RET_OK, ...
&(vc_threadId) )...
} ...
...
break; ...
} ...
...
return( rtnCod ); ...
} ...
//*Create Client Thread ********************************...
/* Create Server Thread ********************************...
char cl_server::create_thread( void ) ...
{ ...
char rtnCod = RET_OK; ...
...
for( ; ; ) ...
{ ...
if( NULL != vc_threadId ) ...
{ ...
SetEvent( vc_events[1] ); ...
} ...
else ...
{ ...
vc_handle = ...
(HANDLE)_beginthreadex( NULL, ...
RET_OK, ...
&cl_server::th_r...
NULL, ...
RET_OK, ...
&(vc_threadId) )...
} ...
...
break; ...
} ...
...
return( rtnCod ); ...
} ...
//*Create Server Thread ********************************...
動作確認
>cl.exe seqSv.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15...
Copyright (C) Microsoft Corporation. All rights reserved.
seqSv.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:seqSv.exe
seqSv.obj
>seqSv.exe 3 localhost
vn_pid = 5564
it takes 16 msec.
This is client's thread.
This is server's thread.
waiting for clients.
a client accepted: 127.0.0.1
session ID: 0
sessions: 1
go next selection.
recvBytes = 7.
server rec: Hello.
go next selection.
recvBytes = 7.
client rec: Hello.
This is client's thread.
Client's thread killed.
recvBytes = 0.
session closed.
go next selection.
go next selection.
This is server's thread.
Server's thread killed.
>
*** 修正履歴 [#ua9ab7c0]
~
*** 課題 [#wae2c1e5]
~
ページ名: