C++/ソケットサンプル1(Linuxサーバ)
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
''[[FrontPage]]''
* ソケットサンプル1(Linuxサーバ) [#z732f996]
Linux上でサーバとして動作するサンプルを解説する。~
[[C++/ソケットサンプル2(Windowsサーバ・クライアント)]]~
[[Java/ソケットサンプル]]
** 制約 [#g4e85c11]
サンプルとして、ホスト名"clove.la"でアクセスできること。~
サンプルとして、ポート"57891"でアクセスできること。~
コンパイルのコマンドラインは"g++ -Wall seqSv.cpp -lpthrea...
~
~
ファイル名: seqSv.cpp
#include <stdio.h> ...
#include <stdlib.h> ...
#include <sys/types.h> ...
#include <sys/time.h> ...
#include <sys/socket.h> ...
#include <netinet/in.h> ...
#include <unistd.h> ...
#include <netdb.h> ...
#include <arpa/inet.h> ...
#include <string.h> ...
#include <pthread.h> ...
//#include <semaphore.h> ...
...
#define BUFF_SIZE_MERE 1024 ...
//#define SV_PORT 4519 ...
#define SV_PORT 57891 ...
#define MAX_CONNS 19 ...
...
const int ADDR_SIZE = sizeof(struct sockaddr_i...
...
static int vc_kill_th_sv = 0; ...
...
void* th_sv( void* vd_data ); ...
void* th_cl( void* vd_data ); ...
...
/* Main ************************************************...
int main( void ) ...
{ ...
int rtnCod = 0; ...
pthread_t svid; ...
// pthread_t clid; ...
...
pthread_create( &svid, NULL, th_sv, NULL ); ...
// pthread_create( &clid, NULL, th_cl, NULL ); ...
// ...
// pthread_join( svid, NULL ); ...
// pthread_join( clid, NULL ); ...
...
getchar(); ...
vc_kill_th_sv = 1; ...
pthread_join( svid, NULL ); ...
...
return( rtnCod ); ...
} ...
//*Main ************************************************...
/* Server Thread ***************************************...
void* th_sv( void* vd_data ) ...
{ ...
int index = 0; ...
static int sessionNum = 0; ...
static int sessionIndicator; ...
int sv_sock; ...
int cl_sock[MAX_CONNS]; ...
int tmp_sock; ...
int clAddrLen; ...
int cnt; ...
...
fd_set fds; ...
fd_set fds_bk; ...
struct timeval timeVal; ...
...
struct sockaddr_in srcAddr; ...
// struct sockaddr_in dstAddr; ...
...
char strBuf[BUFF_SIZE_MERE] = ""; ...
...
struct hostent *host; ...
unsigned int** addrRoot; ...
int recvBytes; ...
...
host = gethostbyname( "clove.la" ); ...
...
memset( cl_sock, 0, sizeof(cl_sock) ); ...
...
for( ; ; ) ...
{ ...
if( NULL == host ) ...
{ ...
printf( "unknown host.\n" ); ...
break; ...
} ...
...
addrRoot = (unsigned int **)host->h_addr_list; ...
if( NULL == *addrRoot ) ...
{ ...
printf( "failed to resolve host name.i\n" );...
break; ...
} ...
...
timeVal.tv_sec = 10; ...
timeVal.tv_usec = 0; ...
...
memset( &srcAddr, 0, sizeof(srcAddr) ); ...
...
srcAddr.sin_port = htons( SV_PORT ); ...
srcAddr.sin_family = AF_INET; ...
srcAddr.sin_addr.s_addr = htonl( INADDR_ANY ); ...
...
sv_sock = socket( AF_INET, SOCK_STREAM, 0 ); ...
index = bind( sv_sock, (struct sockaddr *) &srcA...
if( -1 == index ) ...
{ ...
printf( "failed to bind.\n" ); ...
close( sv_sock ); ...
} ...
...
index = listen( sv_sock, MAX_CONNS ); ...
if( -1 == index ) ...
{ ...
printf( "time out listening.\n" ); ...
close( sv_sock ); ...
} ...
...
clAddrLen = sizeof(srcAddr); ...
...
FD_ZERO( &fds_bk ); ...
FD_SET( sv_sock, &fds_bk ); ...
...
for( ; ; ) ...
{ ...
if( 0 != vc_kill_th_sv ) ...
{ ...
break; ...
} ...
...
memcpy( &fds, &fds_bk, sizeof(fd_set) ); ...
timeVal.tv_sec = 10; ...
timeVal.tv_usec = 0; ...
...
index = select( MAX_CONNS + 1, &fds, NULL, N...
if( 0 == index ) ...
{ ...
printf( "waiting for clients.\n" ); ...
// memcpy( &fds, &fds_bk, sizeof(fd_set) ...
continue; ...
} ...
...
if( FD_ISSET( sv_sock, &fds ) ) ...
{ ...
// cl_sock[sessionNum] = ...
// accept( sv_sock, (struct sockaddr ...
tmp_sock = ...
// accept( sv_sock, (struct sockaddr ...
accept( sv_sock, (struct sockaddr *)...
if( -1 == tmp_sock ) ...
{ ...
printf( "time out accepting. session...
} ...
else ...
{ ...
if( MAX_CONNS == sessionNum ) ...
{ ...
printf( "session full.\n\n" ); ...
// _snprintf_s( strBuf, sizeof(st...
snprintf( strBuf, 16, "%s", "ser...
send( tmp_sock, strBuf, strlen(s...
shutdown( tmp_sock, 2 ); ...
close( tmp_sock ); ...
sessionNum--; ...
continue; ...
} ...
...
for( sessionIndicator = 0; ...
MAX_CONNS > sessionIndicator; s...
{ ...
if( 0 == cl_sock[sessionIndicato...
{ ...
cl_sock[sessionIndicator] = ...
printf( "session ID: %d\n\n"...
FD_SET( tmp_sock, &fds_bk );...
sessionNum++; ...
printf( "sessions: %d\n\n", ...
break; ...
} ...
} ...
} ...
} ...
...
for( cnt = 0; MAX_CONNS > cnt; cnt++ ) ...
{ ...
if( FD_ISSET(cl_sock[cnt], &fds) ) ...
{ ...
tmp_sock = cl_sock[cnt]; ...
recvBytes = recv( tmp_sock, strBuf, ...
printf( "recvBytes = %d.\n\n", recvB...
if( -1 == recvBytes ) ...
{ ...
// errInd = WSAGetLastError(); ...
// if( WSAECONNRESET == errInd ) ...
// { ...
// printf( "session closed.\n...
// } ...
// else ...
// { ...
// printf( "failed to receive...
// printf( "error: %d\n", err...
// } ...
printf( "failed to receive.\n" )...
FD_CLR( tmp_sock, &fds_bk ); ...
cl_sock[cnt] = 0; ...
close( tmp_sock ); ...
sessionNum--; ...
continue; ...
} ...
else if( 0 == recvBytes ) ...
{ ...
printf( "session closed.\n\n" );...
FD_CLR( tmp_sock, &fds_bk ); ...
cl_sock[cnt] = 0; ...
close( tmp_sock ); ...
sessionNum--; ...
continue; ...
} ...
strBuf[recvBytes] = '\0'; ...
printf( "server rec: %s\n", strBuf )...
...
index = send( tmp_sock, strBuf, strl...
if( -1 == index ) ...
{ ...
printf( "failed to send.\n" ); ...
FD_CLR( tmp_sock, &fds_bk ); ...
cl_sock[cnt] = 0; ...
close( tmp_sock ); ...
shutdown( tmp_sock, 2 ); ...
close( tmp_sock ); ...
sessionNum--; ...
continue; ...
} ...
} ...
} ...
} ...
...
break; ...
} ...
...
shutdown( sv_sock, 2 ); ...
close( sv_sock ); ...
...
return( vd_data ); ...
} ...
//*Server Thread ***************************************...
/* Client Thread ***************************************...
void* th_cl( void* vd_data ) ...
{ ...
// int cnt = 0; ...
...
return( vd_data ); ...
} ...
//*Client Thread ***************************************...
動作確認
# g++ -Wall seqSv.cpp -lpthread -L/usr/lib
# ./a.out
session ID: 0
sessions: 1
recvBytes = 7.
server rec: Hello.
recvBytes = 0.
session closed.
*** 修正履歴 [#o8f8a6f9]
~
*** 課題 [#s130c5aa]
クライアントとしての動作は実装していない。~
終了行:
''[[FrontPage]]''
* ソケットサンプル1(Linuxサーバ) [#z732f996]
Linux上でサーバとして動作するサンプルを解説する。~
[[C++/ソケットサンプル2(Windowsサーバ・クライアント)]]~
[[Java/ソケットサンプル]]
** 制約 [#g4e85c11]
サンプルとして、ホスト名"clove.la"でアクセスできること。~
サンプルとして、ポート"57891"でアクセスできること。~
コンパイルのコマンドラインは"g++ -Wall seqSv.cpp -lpthrea...
~
~
ファイル名: seqSv.cpp
#include <stdio.h> ...
#include <stdlib.h> ...
#include <sys/types.h> ...
#include <sys/time.h> ...
#include <sys/socket.h> ...
#include <netinet/in.h> ...
#include <unistd.h> ...
#include <netdb.h> ...
#include <arpa/inet.h> ...
#include <string.h> ...
#include <pthread.h> ...
//#include <semaphore.h> ...
...
#define BUFF_SIZE_MERE 1024 ...
//#define SV_PORT 4519 ...
#define SV_PORT 57891 ...
#define MAX_CONNS 19 ...
...
const int ADDR_SIZE = sizeof(struct sockaddr_i...
...
static int vc_kill_th_sv = 0; ...
...
void* th_sv( void* vd_data ); ...
void* th_cl( void* vd_data ); ...
...
/* Main ************************************************...
int main( void ) ...
{ ...
int rtnCod = 0; ...
pthread_t svid; ...
// pthread_t clid; ...
...
pthread_create( &svid, NULL, th_sv, NULL ); ...
// pthread_create( &clid, NULL, th_cl, NULL ); ...
// ...
// pthread_join( svid, NULL ); ...
// pthread_join( clid, NULL ); ...
...
getchar(); ...
vc_kill_th_sv = 1; ...
pthread_join( svid, NULL ); ...
...
return( rtnCod ); ...
} ...
//*Main ************************************************...
/* Server Thread ***************************************...
void* th_sv( void* vd_data ) ...
{ ...
int index = 0; ...
static int sessionNum = 0; ...
static int sessionIndicator; ...
int sv_sock; ...
int cl_sock[MAX_CONNS]; ...
int tmp_sock; ...
int clAddrLen; ...
int cnt; ...
...
fd_set fds; ...
fd_set fds_bk; ...
struct timeval timeVal; ...
...
struct sockaddr_in srcAddr; ...
// struct sockaddr_in dstAddr; ...
...
char strBuf[BUFF_SIZE_MERE] = ""; ...
...
struct hostent *host; ...
unsigned int** addrRoot; ...
int recvBytes; ...
...
host = gethostbyname( "clove.la" ); ...
...
memset( cl_sock, 0, sizeof(cl_sock) ); ...
...
for( ; ; ) ...
{ ...
if( NULL == host ) ...
{ ...
printf( "unknown host.\n" ); ...
break; ...
} ...
...
addrRoot = (unsigned int **)host->h_addr_list; ...
if( NULL == *addrRoot ) ...
{ ...
printf( "failed to resolve host name.i\n" );...
break; ...
} ...
...
timeVal.tv_sec = 10; ...
timeVal.tv_usec = 0; ...
...
memset( &srcAddr, 0, sizeof(srcAddr) ); ...
...
srcAddr.sin_port = htons( SV_PORT ); ...
srcAddr.sin_family = AF_INET; ...
srcAddr.sin_addr.s_addr = htonl( INADDR_ANY ); ...
...
sv_sock = socket( AF_INET, SOCK_STREAM, 0 ); ...
index = bind( sv_sock, (struct sockaddr *) &srcA...
if( -1 == index ) ...
{ ...
printf( "failed to bind.\n" ); ...
close( sv_sock ); ...
} ...
...
index = listen( sv_sock, MAX_CONNS ); ...
if( -1 == index ) ...
{ ...
printf( "time out listening.\n" ); ...
close( sv_sock ); ...
} ...
...
clAddrLen = sizeof(srcAddr); ...
...
FD_ZERO( &fds_bk ); ...
FD_SET( sv_sock, &fds_bk ); ...
...
for( ; ; ) ...
{ ...
if( 0 != vc_kill_th_sv ) ...
{ ...
break; ...
} ...
...
memcpy( &fds, &fds_bk, sizeof(fd_set) ); ...
timeVal.tv_sec = 10; ...
timeVal.tv_usec = 0; ...
...
index = select( MAX_CONNS + 1, &fds, NULL, N...
if( 0 == index ) ...
{ ...
printf( "waiting for clients.\n" ); ...
// memcpy( &fds, &fds_bk, sizeof(fd_set) ...
continue; ...
} ...
...
if( FD_ISSET( sv_sock, &fds ) ) ...
{ ...
// cl_sock[sessionNum] = ...
// accept( sv_sock, (struct sockaddr ...
tmp_sock = ...
// accept( sv_sock, (struct sockaddr ...
accept( sv_sock, (struct sockaddr *)...
if( -1 == tmp_sock ) ...
{ ...
printf( "time out accepting. session...
} ...
else ...
{ ...
if( MAX_CONNS == sessionNum ) ...
{ ...
printf( "session full.\n\n" ); ...
// _snprintf_s( strBuf, sizeof(st...
snprintf( strBuf, 16, "%s", "ser...
send( tmp_sock, strBuf, strlen(s...
shutdown( tmp_sock, 2 ); ...
close( tmp_sock ); ...
sessionNum--; ...
continue; ...
} ...
...
for( sessionIndicator = 0; ...
MAX_CONNS > sessionIndicator; s...
{ ...
if( 0 == cl_sock[sessionIndicato...
{ ...
cl_sock[sessionIndicator] = ...
printf( "session ID: %d\n\n"...
FD_SET( tmp_sock, &fds_bk );...
sessionNum++; ...
printf( "sessions: %d\n\n", ...
break; ...
} ...
} ...
} ...
} ...
...
for( cnt = 0; MAX_CONNS > cnt; cnt++ ) ...
{ ...
if( FD_ISSET(cl_sock[cnt], &fds) ) ...
{ ...
tmp_sock = cl_sock[cnt]; ...
recvBytes = recv( tmp_sock, strBuf, ...
printf( "recvBytes = %d.\n\n", recvB...
if( -1 == recvBytes ) ...
{ ...
// errInd = WSAGetLastError(); ...
// if( WSAECONNRESET == errInd ) ...
// { ...
// printf( "session closed.\n...
// } ...
// else ...
// { ...
// printf( "failed to receive...
// printf( "error: %d\n", err...
// } ...
printf( "failed to receive.\n" )...
FD_CLR( tmp_sock, &fds_bk ); ...
cl_sock[cnt] = 0; ...
close( tmp_sock ); ...
sessionNum--; ...
continue; ...
} ...
else if( 0 == recvBytes ) ...
{ ...
printf( "session closed.\n\n" );...
FD_CLR( tmp_sock, &fds_bk ); ...
cl_sock[cnt] = 0; ...
close( tmp_sock ); ...
sessionNum--; ...
continue; ...
} ...
strBuf[recvBytes] = '\0'; ...
printf( "server rec: %s\n", strBuf )...
...
index = send( tmp_sock, strBuf, strl...
if( -1 == index ) ...
{ ...
printf( "failed to send.\n" ); ...
FD_CLR( tmp_sock, &fds_bk ); ...
cl_sock[cnt] = 0; ...
close( tmp_sock ); ...
shutdown( tmp_sock, 2 ); ...
close( tmp_sock ); ...
sessionNum--; ...
continue; ...
} ...
} ...
} ...
} ...
...
break; ...
} ...
...
shutdown( sv_sock, 2 ); ...
close( sv_sock ); ...
...
return( vd_data ); ...
} ...
//*Server Thread ***************************************...
/* Client Thread ***************************************...
void* th_cl( void* vd_data ) ...
{ ...
// int cnt = 0; ...
...
return( vd_data ); ...
} ...
//*Client Thread ***************************************...
動作確認
# g++ -Wall seqSv.cpp -lpthread -L/usr/lib
# ./a.out
session ID: 0
sessions: 1
recvBytes = 7.
server rec: Hello.
recvBytes = 0.
session closed.
*** 修正履歴 [#o8f8a6f9]
~
*** 課題 [#s130c5aa]
クライアントとしての動作は実装していない。~
ページ名: