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
A 回答 (3件)
- 最新から表示
- 回答順に表示
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;
}
}
といったような感じです
でもって今改めてみたけど質問者さんが書いたコードでポート開放できてるみたいでした
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 …
ご回答ありがとうございます。
調べていただき、本当にありがとうございます。
早速、とりあえず、実行の方をさせていただいたのですが、
どうも、listenの部分がよくわかりません。
acceptの前まで上書きさせていただいたのですが、
結局listenで接続待ちになっていないようで、すぐにacceptの方に移ってしまい、
acceptでエラーを返してきます。
これは、実は正しいのでしょうか?
Do Loopで抑えておかないといけないのでしょうか?
すいませんが、お願いします。
No.1
- 回答日時:
コネクトできたらそのままsendでデータ送信できるはすです
但し記載コードでは其処まで動いていないと思います
クライアント側ではサーバのIPとポート指定してソケット開かないと
動きませんよ
単純なコードの問題ではなくてソケット通信というのがどんな物か
勉強された方がいいのではないかと思います
http://yonex1.cis.ibaraki.ac.jp/~yonekura/2002ka …
この回答への補足
サーバー側
#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)
ご回答ありがとうございます。
リンク先のページ、拝見させていただきました。
目を通しながら、書き直しているのですが、サーバー側のlisten関数で、接続待ちになりません。(SOCKET_ERRORがすぐに返る)
それと、bind関数で、第二パラメータは『SOCKADDR』型となっていますが、
『SOCKADDR_IN』型を、どうやって指定するのでしょう?
とりあえず、Declareの定義部分で変えてやっています(これがいけないのかと思いますが・・・)
すみませんが、よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
VB6のwinsockでconnectできない
-
エクセル VBA でのCOMポート...
-
TCP/IP通信でのコネクシ...
-
VBとCでのソケット通信について
-
WinSockでの通信プログラムがう...
-
FTPファイル転送の際のアクティ...
-
VC6.0ソケット通信プログラムに...
-
ソケットとそれに基づくストリ...
-
Socket通信の0バイト受信について
-
recv関数でフリーズしてしまう
-
Macターミナルで実行中のプログ...
-
3のつく数字と3の倍数のみを表...
-
VBSの処理中一旦処理を止めて再...
-
vba listviewにおけるtextのAli...
-
緯度、経度の 10進法と 60進法...
-
C# シリアル通信でデータ受信...
-
「ヒープサイズの設定」て何?
-
VBSで応答不要のメッセージボッ...
-
VB6で10進数を32進数に変換する...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
エクセル VBA でのCOMポート...
-
VB6のwinsockでconnectできない
-
Socket通信の0バイト受信について
-
recv関数でフリーズしてしまう
-
UDP通信におけるbind関数について
-
ソケットのrecvの戻り値が0
-
Winsockで接続待ちタイムアウト...
-
UDP通信する時に、相手にどうや...
-
UdpClient 送信元のIPアドレ...
-
ソケット通信 同じポート番号...
-
ソケットのクローズについて
-
空きポートの取得方法
-
Winsockを使わずにVBでSocketを...
-
ソケットでクライアントのipア...
-
ソケット通信
-
ソケットを用いた1対多通信につ...
-
ソケットとそれに基づくストリ...
-
CreateFile関数でCOMポートが開...
-
SIPがNATを越えられない理由
おすすめ情報