第94章 POP3サーバに接続する


今回はPOP3サーバに接続するプログラムの前準備として 必要な関数などの解説をします。



次のような手順で接続します。

1.WSAStartup関数でwinsockを初期化します。
2.socketをオープンします。
3.connect関数でサーバに接続します。
接続するとサーバーから返事が来ます。これをrecv関数で受け取ります。

今回は接続してサーバーから返事が来たらすぐに接続を終了するプログラムを作ります。 これには、サーバーに「QUIT\r\n」コマンドをsendします。

接続を切ったらsocketをクローズしてWSACleanup関数でクリーンアップします。

では、ここで使う関数を見てみましょう。

SOCKET socket(
  int af,       
  int type,     
  int protocol  
);
ソケットを生成します。
afには、アドレスファミリィを指定します。
ここでは、インターネットなのでPF_INETしか使いません。

typeには、ソケットのタイプを指定します。
TCPならSOCK_STREAM、UDPならSOCK_DGRAMを指定します。
ここでは、TCPなのでSOCK_STREAMを指定します。

protocolには、PF_INETの場合0を指定します。

成功すれば、ソケット記述子(ハンドル)が返されます。
失敗した場合は、INVALID_SOCKETが返されます。

int connect(
  SOCKET s,                          
  const struct sockaddr FAR *name,  
  int namelen                        
);
指定のソケットに接続を確立します。
sはソケット記述子です。
nameは、ソケットの名前を指定します。
namelenには、nameの長さを指定します。

成功したら0が返されます。失敗したらSOCKET_ERRORが返されます。

さて、nameはsockaddr構造体へのポインタを指定します。
sockaddr構造体は次のように定義されています。

struct sockaddr {
  u_short    sa_family;
  char       sa_data[14];
};   
このままでは、自由度が大きすぎて使いにくいのでsockaddr_in構造体に 必要事項をセットしてsockaddr構造体に型キャストして使用します。
struct sockaddr_in{
   short sin_family;
   unsigned short sin_port;
   struct in_addr sin_addr;
   char sin_zero[8];
};
sin_familyはアドレスファミリィでAF_INETにします。

sin_portにはポート番号を指定します。

ポート番号はネットワークバイトオーダーに変換する必要があります。
2バイト以上の数値はインターネットでは「ビッグエンディアン」で記録/送信する決まりになっています。
これは、最上位バイトから順に記録/送信することを意味します。
一方インテル社のCPU(Windows)では「リトルエンディアン」が採用されています。 ネットワーク上で採用されているバイトオーダーをネットワークバイトオーダーといいます。

unsigned int値をネットワークバイトオーダーに変換するにはhtons関数を使います。

u_short htons(
  u_short hostshort  
);
(u_shortはunsigned short)

sin_addrはin_addr構造体です。

struct in_addr {
  union {
          struct { u_char s_b1,s_b2,s_b3,s_b4; }   S_un_b;
          struct { u_short s_w1,s_w2; }            S_un_w;
          u_long                                   S_addr;
  } S_un;
};
S_un_bは4つのu_charでフォーマットされたホストのアドレスです。

S_un_wは2つのu_shortでフォーマットされたホストアドレスです。

S_addrはu_longでフォーマットされたホストアドレスです。

sin_zeroはsockaddr構造体とサイズを同じにするためのバディングです。

通常sockaddr_in構造体を設定するには

SOCKADDR_IN sockadd;

sockadd.sin_family = AF_INET;
sockadd.sin_port = htons(110);
sockadd.sin_addr = *((LPIN_ADDR)*lpHost->h_addr_list);
のような感じで行います。
(winsock.hでは

typedef struct sockaddr_in SOCKADDR_IN;

のようにtypedefされています)

lpHostはgethostbynameまたは、gethostbyaddrで取得できますね。

int recv(
  SOCKET s,       
  char FAR *buf,  
  int len,        
  int flags       
);
接続したソケットからデータを読み込みます。
sはソケットです。
bufは読み込んだデータを格納するバッファです。
lenはバッファサイズです。
flagsは0を指定します。

成功したら読み込んだデータの長さ(バイト)を返します。
失敗したらSOCKET_ERRORを返します。

int send(
  SOCKET s,              
  const char FAR *buf,  
  int len,               
  int flags              
);
接続したソケットにデータを送ります。

sはソケットです。
bufは送信するデータを格納するバッファです。
lenはbuf中のデータの長さです。
flagsは通常0を指定します。

成功したら送信したバイト数を返します。
失敗したらSOCKET_ERRORが返されます。

さて、これでPOP3サーバに接続する準備ができました。 次章では実際にPOP3サーバに接続してみます。


[Index][総合Index] [Previous Chapter] [Next Chapter]

Update Feb/23/2004 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。