山口屋~活動日誌~

私生活で主な出来事をピックアップ

ソケット sockaddr addrinfo

2014-08-17 22:17:58 | ソフトウェア開発
<SOCKET設定:旧>

メンバ変数にアクセスして設定

struct sockaddr_in
{
short sin_family;
u_short sin_port;
struct in_Addr sin_addr;
};
// memset(struct sockaddr_in*, 0, sizeof(struct sockaddr_in)) を実行してから使用する
// sin_family = AF_INET;
// sin_port = htons(ポート番号);
// sin_addr.s_addr = inet_addr(IPアドレス);
// または
// sin_port = (getservbyname(サービス名, プロトコル名))->s_port; // プロトコル名はNULLも可能.
// sin_addr.s_addr = (gethostbayname(ホスト名))->h_addr;

connect()やbind()の引数 struct sockaddr* に対し, struct sockaddr_in* をアップキャストして代入する。

<SOCKET設定:新>

getaddrinfo(ホスト名, サービス名, const struct addrinfo* hints, struct addrinfo* *res) で設定

struct addrinfo
{
...
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
...
struct sockaddr* ai_addr;
...
};
// 引数 hints の使用
// memset(struct addrinfo*, 0, sizeof(struct addrinfo)) を実行してから使用する
// ai_family = AF_INET;
// ai_socktype = SOCK_STREAM または SOCK_DGRAM ;
// SOCK_STREAM は TCP, SOCK_DGRAM は UDP の使用を意味する

socket()の引数に対し, (struct addrinfo* res)->ai_family, (struct addrinfo* res)->ai_socktype, (struct addrinfo* res)->ai_protocol を代入することもできる。
connect()やbind()の引数 struct sockaddr*, int に対し, (struct addrinfo* res)->ai_addr, (struct addrinfo* res)->ai_addrlen を代入する。

int getnameinfo(const struct sockaddr*, socklen_t, char*, socklen_t, char*, socklen_t, int);
struct sockaddr* からホスト名, サービス名を取得する。

<SOCKET作成>

socket(int af, int type, int protocol)
// 1つ目の引数 = AF_INET
// struct sockaddr_in の使用を意味する
// 2つ目の引数 = SOCK_STREAM または SOCK_DGRAM
// SOCK_STREAM は TCP, SOCK_DGRAM は UDP の使用を意味する
// 3つ目の引数 = 0
// 0 であればデフォルト値が選択される
※WinSockでは、エラー時、INVALID_SOCKETを返す。

accept()またはrecvfrom()を実行するサーバー側ではbind()を実行して必要な情報を設定する。

bind(SOCKET, struct sockaddr*, int):作成済のSOCKETにstruct sockaddrの情報を設定する
※WinSockでは、エラー時、SOCKET_ERRORを返す。

<接続型アプリケーション用SOCKET>

サーバー側では送受信SOCKETとは別にクライアント接続SOCKETを以下の関数を実行して待機しておく。

listen(SOCKET, int):作成済のSOCKETを待機する
※WinSockでは、エラー時、SOCKET_ERRORを返す。

送受信SOCKETを以下の関数を実行して用意する。
accept()ではSOCKETが作成されるため、int型の引数がポインタとなっている。struct sockaddr* には struct sockaddr_storage* をキャストして渡す。

accept(SOCKET, struct sockaddr*, int *):接続済のSOCKETを作成する(サーバー側)
connect(SOCKET, struct sockaddr*, int):作成済のSOCKETを接続する(クライアント側)
※WinSockでは、エラー時、accept()はINVALID_SOCKET、connect()はSOCKET_ERRORを返す。
※WSAGetLastError()でエラーの詳細を取得できる。

int recv(SOCKET, char*, int, int);
int send(SOCKET, char*, int, int);
※WinSockでは、エラー時、SOCKET_ERRORを返す。

<非接続型アプリケーション用SOCKET>

int recvfrom(SOCKET, char*, int, int, struct sockaddr*, int *);
int sendto(SOCKET, char*, int, int, struct sockaddr*, int);
※WinSockでは、エラー時、SOCKET_ERRORを返す。


<select()>

winsockではselect()の第1引数は無視される。
Yahoo!知恵袋:winsock の select() の第一引数について知りたいです。

Geekなぺーじ:selectを横から止める方法

<ポート番号>

@network Cisco・アライド実機で学ぶ:ポート番号の役割
ITpro:TCPとUDPの本質を押さえる - Part3 UDP編 - 面倒な手順をカット、信頼性より軽さと速さ

<参考URL>

WinSock関数一覧
Windows ソケットのエラー コード、値、および意味
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Windows ソケット WinSock2.0

2014-08-14 17:53:16 | ソフトウェア開発
WinSockのバージョン2.0を使用する場合には以下の記述をする。

<winsock2.h → windows.h の順でインクルードする場合>

#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")

<windows.h → winsock2.h の順でインクルードする場合>

#define _WINSOCKAPI_ // Prevent includsion of winsock.h in windows.h
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")

_WINSOCKAPI_マクロはwinsock2.h、windows.hでインクルードされるwinsock.hの両方で定義されているが、windows.hをインクルードする前に定義しておけば、windows.hからインクルードされるwinsock.hが、後からインクルードされるwinsock2.hへ衝突することによるエラーを防ぐことができる。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする