テクニカルノート05: WinSock

November 25, 2005

© NSB Corporation. All rights reserved.

Go to English page.
マイクロソフト社のドキュメントも参考にして下さい。

NS Basic/CE はMicrosoftの標準WinSockオブジェクトを使用して、インタネットへのアクセスを可能にします。 WinSockオブジェクトがお使いのWindows CEデバイスにインストールされていて、レジストリに正しく設定されていることを確認して下さい。お使いのシステムにこのモジュールを読ませる方法につきましては、テクニカルノート01を参照して下さい。

ご使用になる前に、以下のコマンドを使用し、WinSockを初期化する必要があります。

addObject "winsock"

メモ

1. (ユーザから) 「MS WINSOCKコントロールを使おうと試してきました。最初のメッセージを受け取った後、入ってくるメッセージの受信が止まってしまいます。そこでIPwork 5をダウンロードして、そのocxを自分のiPaq3955へインストールしました。オブジェクト名、メソッド名、パラメータを変更したら、初めて動作しました。

PocketPCはUSBポートを使って接続されている時、そのはTCP接続として扱われることを発見しました。ですから、コードを変更することなしに、USB接続、ネットワークカード、またはRFカードを使って、私のNT/2000上のTCPポートサーバーへ接続し、データのやり取りができました。PocketPCをインテリジェントなクライアントとして利用することも可能です。私はAccess、SQL Server、Oracleデータベースとやり取りするTCPサーバーを持っています。これはマイクロソフトのライブラリと複雑なテクノロジーにより負荷を避けながら、多層(multi-tier)開発を可能にしてくれます。」

2. WiFi接続にWinsockを使う:
仮にあなたが接続しようとしているシステムのIPアドレスがインターネットと無関係であっても、winsock接続はDNSサーバーへの接続を試み、アドレスを取得しようとします(または80秒の遅延)。これはMSの問題だと思います。DNSサーバーへの参照を求める前にローカルアドレスを見るようにwinsockを修正してくれると良いのですが・・・。

プロパティ

プロパティは値を設定するか、または値を返します。シンタックスは、

Winsock.bytesReceived '受信したバイト数を受け取る

 

BytesReceived

受信バッファ内のバイト数を得る。

LocalHostName

ローカルホストの名前を文字列で得る。

LocalIP

"255.255.255.255"の形式でIPアドレスを得る。

LocalPort GetData

ローカルポートを得る/設定する。0の使用でランダムに一つをつかむ。

Protocol

プロトコルを得る/設定する。0=TCP, 2=IRDA

RemoteHost

遠隔ホスト名を得る/設定する。

RemoteHostIP

遠隔ホストのIPアドレスを得る/設定する。

RemotePort

接続する為に遠隔ポートを得る/設定する。80はwebサーバー。完全なリストはAppendix Aに記載されています。

SocketHandle

Winsockレイヤとの通信に使われるソケットハンドルを得る。

State

0-closed(閉じている)
1-open(開いている)
2-listening(受信中(聞き取り中))
7-connected(接続されている)
9-error(エラー)

ServiceName

サービス名を得る/設定する。

 

メソッド

Accept

(ConnectionRequestイベントから)入ってくる接続を受け入れる。

Close

接続を閉じる。エラー値を返す。

Connect

接続を確立する。成功の場合は0を返す。

GetData

データの現在のブロックを返す。

Listen

ソケットを作り、それを受信(聞き取り)モードにする。

SendData(data)

遠隔コンピュータにデータを送る。

 

イベント

イベントはプログラム内にサブルーチンが存在する場合に、それらのサブルーチンコールをもたらします。サブルーチンには<objectName>_eventNameの名前を付けなければなりません。

例えば、Outputオブジェクト内のクリックを捕えるには、次の事が必要です。

sub winsock_dataArrival
'
データの受信を処理するコード
end sub

Close

遠隔コンピュータによって接続が閉じられた。Closeメソッドを使ってデバイス側の接続も閉じて下さい。

ConnectionRequest

遠隔コンピュータの接続リクエスト。RemoteHostIP, RemoteHostを設定。

DataArrival(n)

受取っているデータ。n はその数。

Error(e)

エラーコード。Appendix Bを参照。

SendComplete

SendData が完了した時、送られる。

SendProgress(b,r)

データが送られている間。 B=送られたバイト数、r- 残りのバイト数

 

注記

Transfer Control Protocol (TCP)は遠隔コンピュータへの接続の確立と維持を可能にします。この接続により、コンピュータ同士がデータの交換を出来ます。

クライアントアプリケーションは、サーバーコンピュータの名前またはIPアドレス(RemoteHostプロパティ)、さらにポート(RemotePortプロパティ)を知る必要があります。一つの接続を作る為には、Connectメソッドを呼んで下さい。

サーバーアプリケーションは、受信する為のポート(LocalPortプロパティ)を設定し、Listenメソッドを呼ぶ必要があります。クライアントが接続のリクエストをした時、ConnectionRequestイベントが送られます。接続を完成させる為に、ConnectionRequestイベント内でAcceptメソッドを呼んで下さい。

一旦接続が作られると、どちらのコンピュータからでも、データの送受信が出来ます。データを受取ると、DataArrivalイベントが発生します。データを受取るには、DataArrivalサブルーチンの中で、GetDataメソッドを使用して下さい。

サンプル

rem show a simple retrieval of a web page
addobject "winsock.winsock.1","winsock"
winsock.remotehost="www.nsbasic.com"
winsock.remoteport=80
winsock.connect
strData="GET http://www.nsbasic.com/ce/PR/pr.981012.html" & vbCrLf & vbCrLf
print strData
winsock.sendData strData

private sub winsock_DataArrival(byval bytesTotal)
  dim rdata
  print "data arrival"
  winsock.close
  winsock.connect
  winsock.getData rData
  print rData
end sub

private sub winsock_error(code, desc)
  print "winsock error:" & code & " " & description
end sub

 

Appendix A: 標準ポート番号表

tcpmux          1/tcp                           # TCP port multiplexer 
(RFC1078)
echo            7/tcp
echo            7/udp
discard         9/tcp           sink null
discard         9/udp           sink null
systat          11/tcp          users
daytime         13/tcp
daytime         13/udp
netstat         15/tcp
qotd            17/tcp          quote
chargen         19/tcp          ttytst source
chargen         19/udp          ttytst source
ftp             21/tcp
telnet          23/tcp
smtp            25/tcp          mail
time            37/tcp          timserver
time            37/udp          timserver
rlp             39/udp          resource        # resource location
nameserver      42/tcp          name            # IEN 116
whois           43/tcp          nicname
domain          53/tcp          nameserver      # name-domain server
domain          53/udp          nameserver
mtp             57/tcp                          # deprecated
bootps          67/udp          bootp           # bootp server
bootpc          68/udp                          # bootp client
tftp            69/udp
gopher          70/tcp
rje             77/tcp          netrjs
finger          79/tcp
link            87/tcp          ttylink
webserver       80/tcp
supdup          95/tcp
hostnames       101/tcp         hostname        # usually from sri-nic
tsap            102/tcp                         # part of ISODE.
pop2            109/tcp                         # old pop port
pop             110/tcp         pop3 postoffice
sunrpc          111/tcp
sunrpc          111/udp
ident           113/tcp         auth tap authentication
sftp            115/tcp
uucp-path       117/tcp
nntp            119/tcp         readnews untp   # USENET News Transfer 
Protocol
ntp             123/udp         ntpd
imap            143/tcp
snmp            161/udp                         # network time protocol
snmp-trap       162/udp
smux            199/tcp

 

Appendix B: ERRORイベントによって返されるエラーコード

sckOutOfMemory

7

メモリ不足

sckInvalidPropertyValue

380

プロパティ値が無効

sckGetNotSupported

394

プロパティが読めない

sckSetNotSupported

383

プロパティは書き込み禁止

sckBadState

40006

リクエストされた処理またはリクエスト用には、間違ったプロトコルか接続状態

sckInvalidArg

40014

ファンクションに渡された引数が、正しいフォーマットでないか、指定された範囲でない

sckSuccess

40017

成功

sckUnsupported

40018

サポートしていないvariantタイプ

sckInvalidOp

40020

現在の状態には無効のオペレーション

sckOutOfRange

40021

引数が範囲外

sckWrongProtocol

40026

リクエストされた処理またはリクエスト用には、間違ったプロトコル

sckOpCanceled

1004

オペレーションがキャンセルされた

sckInvalidArgument

10014

リクエストされたアドレスはBroadcastアドレスなのに、フラグが設定されていない

sckWouldBlock

10035

ソケットはnonblockingで、指定されたオペレーションはblockingをする

sckInProgress

10036

blocking Winsockオペレーションがプロセス中

sckAlreadyComplete

10037

オペレーションが完了している。なんのblockingオペレーションもプロセス中でない

sckNotSocket

10038

descriptor がソケットでない

sckMsgTooBig

10040

datagram がバッファに納めるには大きすぎ、一部を切り落とされた

sckPortNotSupported

10043

指定のポートはサポートされていない

sckAddressInUse

10048

アドレスが使用中

sckAddressNotAvailable

10049

ローカルコンピュータからは、使用不可能なアドレス

sckNetworkSubsystemFailed

10050

ネットワーク サブシステムの停止

sckNetworkUnreachable

10051

このホストからは現在ネットワークへアクセス出来ない

sckNetReset

10052

SO_KEEPALIVEが設定されている時、接続の時間切れ

sckConnectAborted

11053

時間切れまたは他の不履行により、接続の中断された

sckConnectionReset

10054

遠隔側により接続がリセットされた

sckNoBufferSpace

10055

バッファスペースに空きがない

sckAlreadyConnected

10056

ソケットは既に接続されている

sckNotConnected

10057

ソケットが接続されていない

sckSocketShutdown

10058

ソケットがシャットダウンされている

sckTimedout

10060

ソケットがシャットダウンされている

sckConnectionRefused

10061

接続が強制的に拒否された

sckNotInitialized

10093

WinsockInitが先に呼ばれるべき

sckHostNotFound

11001

信頼のある応答:ホストが見つからない

sckHostNotFoundTryAgain

11002

信頼のない応答:ホストが見つからない

sckNonRecoverableError

11003

回復不能エラー

sckNoData

11004

有効な名前、リクエストされたタイプにデータレコードがない