• 締切済み

ActiveBasic インターネットを通じてソフト間で通信する

AB 4.23.00を使用しています。 今回、ネットワークのプログラムの勉強を始め、とりあえず、 ネットワークを通して、ソフト間で簡単なチャットが出来るものを作ってみようと思い、作り始めました。 以前、CreateMailslot関数などで出来ると思い、探し回ったのですが、どうしても出来ないので、質問させていただいたところ、『それでは出来ない』とのこと(http://oshiete1.goo.ne.jp/qa5833366.html)だったので、 新たな方法を探していたところ、ソケットというものを使えば出来るというようなことが書かれているページを見つけ、早速参考にさせていただいています。 ですが、どうも、構造というか、その辺がよく分かっていないので、 どこにどの値をどう入れればいいのか・・・などがよく分かりません。 送信用のプログラムは、おそらく書けていると思いますが(一応貼らせていただきます)、 受信用のプログラムでちょっとつまずいています。 connect関数の接続先はどう指定すればいいのか、ということです。 ご存知の方、いらっしゃいましたら、ご教授の方、お願いします。 【送信用】 #console #include <api_winsock2.sbp> Declare Function bind Lib "wsock32.dll" (s As Long,ByRef sName As sockaddr,namelen As Long) As Long Declare Function listen Lib "wsock32.dll" (s As Long,backlog As Long) As Long Declare Function accept Lib "wsock32.dll" (s As Long,ByRef addr As sockaddr,ByRef addrlen As Long) As Long Dim wsaData As WSADATA WSAStartup(MAKELONG(2,0),wsaData) Print "WSAStartup--->"+Date$()+" "+Time$() Dim s As DWord s=socket(AF_INET,SOCK_STREAM,0) If s=0 Then Print "Error-------->Cannot Socket Create" Sleep(-1) End If Dim sar As SOCKADDR With sar .sa_family=AF_INET End With If bind(s,sar,Len(sar))<>0 Then Print "Error-------->BIND ERROR" Sleep(-1) End If Dim sarlen As Long Dim news As DWord listen(s,128) news=accept(s,sar,sarlen) Dim buf[256] As Byte recv(news,buf,256,0) send(news,"HELLO",lstrlen("HELLO"),0) closesocket(s) closesocket(news) Print "SENDED" Sleep(-1) ----------------------------------------------------------------- 【受信用(途中まで)】 #console #include <api_winsock2.sbp> Declare Function bind Lib "wsock32.dll" (s As Long,ByRef sName As sockaddr,namelen As Long) As Long Declare Function listen Lib "wsock32.dll" (s As Long,backlog As Long) As Long Declare Function accept Lib "wsock32.dll" (s As Long,ByRef addr As sockaddr,ByRef addrlen As Long) As Long Dim wsaData As WSADATA WSAStartup(MAKELONG(2,0),wsaData) Print "WSAStartup--->"+Date$()+" "+Time$() Dim s As DWord s=socket(AF_INET,SOCK_STREAM,0) If s=0 Then Print "Error-------->Cannot Socket Create" Sleep(-1) End If Dim sar As SOCKADDR With sar .sa_family=AF_INET End With If bind(s,sar,Len(sar))<>0 Then Print "Error-------->BIND ERROR" Sleep(-1) End If Dim sock_sin As SOCKADDR_IN With sock_sin .sin_family=AF_INET End With If connect(s,sock_sin,Len(sock_sin))<>0 Then Print "Error-------->connect ERROR" Sleep(-1) End If

みんなの回答

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.3

>結局listenで接続待ちになっていないようで、すぐにacceptの方に移ってしまい、 >acceptでエラーを返してきます。 動きとしてはそれであっています(実際此方でも同じです) 私が確認したのも listen 関数で該当ポート接続待ちにした状態で Sleep(-1) 関数コールして その時にツールから接続が出来るか確認しただけです (動いていない時接続エラー・動かしてる時接続OKの確認しただけ) その後の動作(プログラミング)はActiveBasicでどのようにやればいいのかわからなかったので・・・・ > Do Loopで抑えておかないといけないのでしょうか? 普通は(かどうか知りませんが大抵の書籍などでは) その後は SelectSocket 関数などを使ってイベント待ち状態として イベントがコールされた時そちらの関数から Accept/Read/Write 等の関数を コールしていると思います (実際私もそのような使い方しかしたことがありませんが やり方によってコールバック関数でもいいかもしれません) これは基本的には 永久ループで accept 呼び続けるのと同じことになるのではないかと思います (いかんせんやったこと無いので自信なし) あくまでCとしてのサンプルになりますが (以下VCで作ったソケット部分の切り貼り 単純に切り貼りしてるので大文字小文字入り乱れてます) メイン側で   Listen();   WSAAsyncSelect(SockSrv, hwnd_maindlg, WM_USERSOCKET_OFFSET, FD_ACCEPT | FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE); // 非ブロッキング型 上記 hwnd_maindlg 側で ON_MESSAGE(WM_USERSOCKET_OFFSET, OnSocketEvent) void C***::OnSocketEvent(WPARAM wParam, LPARAM lParam) {   switch (WSAGETSELECTEVENT(lParam)){   case FD_ACCEPT:     Accept();     break;   case FD_READ: break;   case FD_WRITE: break;   case FD_CONNECT: break;   case FD_CLOSE: break;   default: break;   } } といったような感じです でもって今改めてみたけど質問者さんが書いたコードでポート開放できてるみたいでした

すると、全ての回答が全文表示されます。
  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.2

構文(文法)も知らないのにやってみました 以下のコードでサーバポートが待ち受け状態になることまでは確認しました (クライアントが接続に成功することを確認) また気が向いたら調べるかもしれないけどあまり期待はしない方がいいです (ここまでで物好きにも数時間かかったので・・・・・さすが文法知らず) テストその他で要らないプリント文などもそのまま載せてますが削除してください Declare Function bind Lib "ws2_32.dll" (s As DWord,ByRef name As SOCKADDR_IN,namelen As Long) As Long Declare Function listen Lib "ws2_32.dll" (s As DWord,backlog As Long) As Long Declare Function accept Lib "ws2_32.dll" (s As DWord,ByRef addr As SOCKADDR_IN,ByRef addrlen As Long) As Long Dim wsaData As WSADATA print wsaData.wVersion WSAStartup(MAKELONG(2,2),wsaData) Print "WSAStartup--->"+Date$()+" "+Time$() print wsaData.wVersion Dim s As DWord s=socket(AF_INET,SOCK_STREAM,0) Print s, AF_INET, SOCK_STREAM If s=0 Then Print "Error-------->Cannot Create Socket" Sleep(-1) End If Dim sar As SOCKADDR Dim sar_in As SOCKADDR_IN Print sar_in.sin_family FillMemory(VarPtr(sar_in),Len(sar_in),0)   ------ クリアが必要 Print sar_in.sin_family With sar_in .sin_family=AF_INET .sin_port=htons(2000)       -------- とりあえずポート2000でサービス動作                   ------- 1024以下は予約されてるので使ってはいけません rem .sin_addr=htonl(0.0.0.0)    ----- サーバ側なのでとりあえず不要                   ----- クライアントでは inet_addr を使います End With With sar .sa_family=AF_INET End With If bind(s,sar_in,Len(sar_in))<>0 Then Print "Error-------->BIND ERROR" Sleep(-1) End If Dim sarlen As Long Dim news As DWord Print "Listn Start" If listen(s,1)=SOCKET_ERROR Then Print "Error-------->LISTEN ERROR" Sleep(-1) End If 接続確認として以下のツールを使用しました http://download.goo.ne.jp/software/contents/soft/win95/net/se296044.html

if-so-at
質問者

お礼

ご回答ありがとうございます。 調べていただき、本当にありがとうございます。 早速、とりあえず、実行の方をさせていただいたのですが、 どうも、listenの部分がよくわかりません。 acceptの前まで上書きさせていただいたのですが、 結局listenで接続待ちになっていないようで、すぐにacceptの方に移ってしまい、 acceptでエラーを返してきます。 これは、実は正しいのでしょうか? Do Loopで抑えておかないといけないのでしょうか? すいませんが、お願いします。

すると、全ての回答が全文表示されます。
  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.1

コネクトできたらそのままsendでデータ送信できるはすです 但し記載コードでは其処まで動いていないと思います クライアント側ではサーバのIPとポート指定してソケット開かないと 動きませんよ 単純なコードの問題ではなくてソケット通信というのがどんな物か 勉強された方がいいのではないかと思います http://yonex1.cis.ibaraki.ac.jp/~yonekura/2002kadai/lecture03.html

if-so-at
質問者

お礼

ご回答ありがとうございます。 リンク先のページ、拝見させていただきました。 目を通しながら、書き直しているのですが、サーバー側のlisten関数で、接続待ちになりません。(SOCKET_ERRORがすぐに返る) それと、bind関数で、第二パラメータは『SOCKADDR』型となっていますが、 『SOCKADDR_IN』型を、どうやって指定するのでしょう? とりあえず、Declareの定義部分で変えてやっています(これがいけないのかと思いますが・・・) すみませんが、よろしくお願いします。

if-so-at
質問者

補足

サーバー側 #console #include <api_winsock2.sbp> Declare Function bind Lib "wsock32.dll" (s As Long,ByRef sName As sockaddr_in,namelen As Long) As Long Declare Function listen Lib "wsock32.dll" (s As Long,backlog As Long) As Long Declare Function accept Lib "wsock32.dll" (s As Long,ByRef addr As sockaddr,ByRef addrlen As Long) As Long Dim wsaData As WSADATA WSAStartup(MAKELONG(2,0),wsaData) Print "WSAStartup--->"+Date$()+" "+Time$() Dim s As DWord s=socket(AF_INET,SOCK_STREAM,0) If s=0 Then Print "Error-------->Cannot Create Socket" Sleep(-1) End If Dim sar As SOCKADDR Dim sar_in As SOCKADDR_IN With sar_in .sin_family=AF_INET .sin_port=htons(10000) .sin_addr=htonl(0.0.0.0) End With With sar .sa_family=AF_INET End With If bind(s,sar_in,Len(sar_in))<>0 Then Print "Error-------->BIND ERROR" Sleep(-1) End If Dim sarlen As Long Dim news As DWord If listen(s,1)=SOCKET_ERROR Then Print "Error-------->LISTEN ERROR" Sleep(-1) End If news=accept(s,sar,sarlen) If news=INVALID_SOCKET Then Print "Error-------->ACCEPT ERROR" End If Dim buffer[1024] As Byte Dim bErr As Long bErr=recv(news,buffer,1024,MSG_OOB) If bErr=0 or SOCKET_ERROR Then Print "Error-------->RECV ERROR AS "+Str$(bErr) Sleep(-1) End If closesocket(s) closesocket(news)

すると、全ての回答が全文表示されます。

関連するQ&A