>> winsock2 からの続き
前回作った winsock2 を使った通信プログラムでは IP、ポートを直に書いていました。
これを外部の ini ファイルから取得するようにします。
◆環境
OS |
Windows XP Professional Version 2002 Service Pack 3 |
VC |
Microsoft Visual Studio 2008 Version 9.0.30729.1 SP |
ini ファイルの値は GetPrivateProfileString 関数で取得します。
まずはサーバー側のプログラムを修正します。
winsock2TestServer.cpp
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
|
// winsock2TestServer.cpp : メイン プロジェクト ファイルです。
#include "stdafx.h"
#include "winsock2.h"
#include <iostream>
using namespace std;
using namespace System;
#pragma comment( lib, "ws2_32.lib" )
int main(array<System::String ^> ^args)
{
wchar_t port_number[10];
DWORD val =
GetPrivateProfileString( L"TCPIP"
, L"Port_Number"
, L"NULL"
, &port_number[0]
, sizeof( port_number )
, L"./winsock2TestServer.ini"
);
wprintf( L"%s\n", port_number );
wchar_t listen_number[10];
GetPrivateProfileString( L"TCPIP"
, L"Listen_Number"
, L"NULL"
, &listen_number[0]
, sizeof( listen_number )
, L"./winsock2TestServer.ini"
);
wprintf( L"%s\n", listen_number );
WSADATA wsaData;
int ret;
SOCKET sock;
int len;
SOCKET client_sock;
struct sockaddr_in addr;
struct sockaddr_in client;
// winsock2の初期化
ret = WSAStartup( MAKEWORD( 2, 0 ), &wsaData );
if ( ret != 0 )
{
switch( ret )
{
case WSASYSNOTREADY:
printf( "WSASYSNOTREADY\n" );
break;
case WSAVERNOTSUPPORTED:
printf( "WSAVERNOTSUPPORTED\n" );
break;
case WSAEINPROGRESS:
printf( "WSAEINPROGRESS\n" );
break;
case WSAEPROCLIM:
printf( "WSAEPROCLIM\n" );
break;
case WSAEFAULT:
printf( "WSAEFAULT\n" );
break;
default:
break;
}
exit( -1 );
}
printf( "WSAStartup successful.\n" );
// ソケットの作成
sock = socket( AF_INET, SOCK_STREAM, 0 );
if ( sock == INVALID_SOCKET )
{
printf( "error : %d\n", WSAGetLastError() );
exit( -2 );
}
printf( "socket successful.\n" );
// ソケットの設定
addr.sin_family = AF_INET;
addr.sin_port = htons( _wtoi( port_number ) );
addr.sin_addr.S_un.S_addr = INADDR_ANY;
ret = bind( sock
, ( struct sockaddr* )&addr
, sizeof( addr )
);
if ( ret == SOCKET_ERROR )
{
printf( "error : %d\n", WSAGetLastError() );
exit( -3 );
}
printf( "bind successful.\n" );
// TCPクライアントからの接続要求を待てる状態にする
ret = listen( sock, _wtoi( listen_number ) );
if ( ret == SOCKET_ERROR )
{
printf( "error : %d\n", WSAGetLastError() );
exit( -4 );
}
printf( "listen successful.\n" );
// TCPクライアントからの接続要求を受け付ける
len = sizeof( client );
client_sock = accept( sock
, ( struct sockaddr* )&client
, &len
);
printf( "accepted connection from %s (%d)\n"
, inet_ntoa( client.sin_addr )
, ntohs( client.sin_port )
);
// メッセージ送信
char* msg = "HELLO winsock2!!";
send( client_sock, msg, strlen( msg ), 0 );
// TCPセッションの終了
closesocket( client_sock );
// winsock2の終了処理
WSACleanup();
printf( "WSACleanup successful.\n" );
return 0;
}
|
|
サーバー側の ini ファイルは以下のようになります。
続いてクライアント側のプログラムを修正します。
winsock2TestClient.cpp
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
|
// winsock2TestClient.cpp : メイン プロジェクト ファイルです。
#include "stdafx.h"
#include "winsock2.h"
#include <comdef.h>
#include <iostream>
using namespace std;
using namespace System;
#pragma comment( lib, "ws2_32.lib" )
int main(array<System::String ^> ^args)
{
wchar_t port_number[10];
DWORD val =
GetPrivateProfileString( L"TCPIP"
, L"Port_Number"
, L"NULL"
, &port_number[0]
, sizeof( port_number )
, L"./winsock2TestClient.ini"
);
wprintf( L"%s\n", port_number );
wchar_t server_ip_address[20];
GetPrivateProfileString( L"TCPIP"
, L"Server_IP_Address"
, L"NULL"
, &server_ip_address[0]
, sizeof( server_ip_address )
, L"./winsock2TestClient.ini"
);
wprintf( L"%s\n", server_ip_address );
WSADATA wsaData;
int ret;
SOCKET sock;
char buf[32];
struct sockaddr_in server;
ret = WSAStartup( MAKEWORD( 2, 0 ), &wsaData );
if ( ret != 0 )
{
switch( ret )
{
case WSASYSNOTREADY:
printf( "WSASYSNOTREADY\n" );
break;
case WSAVERNOTSUPPORTED:
printf( "WSAVERNOTSUPPORTED\n" );
break;
case WSAEINPROGRESS:
printf( "WSAEINPROGRESS\n" );
break;
case WSAEPROCLIM:
printf( "WSAEPROCLIM\n" );
break;
case WSAEFAULT:
printf( "WSAEFAULT\n" );
break;
default:
break;
}
exit( -1 );
}
printf( "WSAStartup successful.\n" );
sock = socket( AF_INET, SOCK_STREAM, 0 );
if ( sock == INVALID_SOCKET )
{
printf( "error : %d\n", WSAGetLastError() );
exit( -2 );
}
printf( "socket successful.\n" );
// 接続先指定用構造体の準備
server.sin_family = AF_INET;
server.sin_port = htons( _wtoi( port_number ) );
server.sin_addr.S_un.S_addr
= inet_addr( ( const char* )_bstr_t( server_ip_address ) );
// サーバに接続
connect( sock
, ( struct sockaddr* )&server
, sizeof( server )
);
// サーバからデータを受信
memset( buf, 0, sizeof( buf ) );
int n = recv( sock, buf, sizeof( buf ), 0 );
if ( n == SOCKET_ERROR )
{
switch( WSAGetLastError() )
{
case WSAENOTCONN:
printf( "ソケットが接続されていません。\n" );
exit( -10 );
default:
printf( "error : %d\n", WSAGetLastError() );
exit( -11 );
}
}
printf( "%d, %s\n", n, buf );
// winsock2の終了処理
WSACleanup();
printf( "WSACleanup successful.\n" );
return 0;
}
|
|
クライアント側の ini ファイルは以下のようになります。
ビルド後、前回と同じくサーバー -> クライアントの順で実行したら上手く動作しました。
送信する文字が今は「HELLO winsock2!!」を直に書いていますので、これを標準入力から取り込むようにしたいと思います。
▲ PageTop ■ Home
Copyright (C) 2012 ymlib.com