C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: VB6⇒VB2008のソケット通信コンバージョンに関して


(過去ログ 91 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■54301 / inTopicNo.1)  VB6⇒VB2008のソケット通信コンバージョンに関して
  
□投稿者/ サンプラザ (1回)-(2010/10/13(Wed) 11:50:13)

分類:[VB.NET/VB2005 以降] 

開発環境:Windows XP
使用言語:Visual Studio 2008

現在、VB6からVB2008へソケット通信コンバージョンを行っています。
VB6で「wsock32.dll」をAPI宣言で使用していたので、VB2008でも同様のAPIを使用して
ソケット通信を実現しようとしているのですが、コネクト処理のConnectSocketメソッドで
エラー番号:10038が返ってきます。
※VB2008固有のソケットクラスは時間がないため、使用しない方針で進めています

ネットで調べたところ、
 「指定されたソケットが無効である。
  ソケットハンドルとして無効な値がソケット関数に渡された。」
と記入されていたので、引数に問題があるかと思い、VB6とAPI宣言を比較していたのですが、
VB2008初心者の私だけでは中々解決策が見つかりません。

お力添えをお願いいたします。


以下ソースコードを抜粋いたします。

◆宣言部◆
Public Declare Function ConnectSocket Lib "wsock32.dll" Alias "connect" (ByRef s As Integer, ByRef sName As sockaddr, ByRef namelen As Integer) As Integer
Public Declare Function GetSocketName Lib "wsock32.dll" Alias "getsockname" (ByRef s As Integer, ByRef sName As sockaddr, ByRef namelen As Integer) As Integer

'バイトオーダー変換
Public Declare Function htonl Lib "wsock32.dll" (ByVal hostlong As Integer) As Integer
Public Declare Function htons Lib "wsock32.dll" (ByVal hostshort As Integer) As Short
Public Declare Function ntohl Lib "wsock32.dll" (ByVal netlong As Integer) As Integer
Public Declare Function ntohs Lib "wsock32.dll" (ByVal netshort As Integer) As Short

' ソケットアドレス(IPおよびポート番号)
  Structure sockaddr
  Dim sin_family As Short
  Dim sin_port As Short
    Dim sin_addr As Integer
  <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=8 + 1)> Dim sin_zero As String
  End Structure


◆処理部◆
uState(Index) = sckHostResolved
With RemoteHost
.sin_family = AF_INET
.sin_port = htons(uRemotePort(Index))
.sin_addr = uRemoteHostIP(Index)
.sin_zero = Space(8).ToString
End With
With LocalHost
.sin_family = 0
.sin_port = 0
.sin_addr = 0
.sin_zero = Space(8).ToString
End With

If ConnectSocket(SocketHandle(Index), RemoteHost, Len(RemoteHost)) = SOCKET_ERROR Then
LastErrorCode(Index) = Err.LastDllError
If LastErrorCode(Index) <> sckWouldBlock Then
Exit Function
End If
LastErrorCode(Index) = 0
uState(Index) = sckConnecting
size = Len(LocalHost)
If GetSocketName(SocketHandle(Index), LocalHost, size) <> SOCKET_ERROR Then
uLocalPort(Index) = LocalHost.sin_port 'LocalHost.sin_port(0) * 256 + LocalHost.sin_port(1)
Else
uLocalPort(Index) = 0
End If
Connect = True
End If



引用返信 編集キー/
■54303 / inTopicNo.2)  Re[1]: VB6⇒VB2008のソケット通信コンバージョンに関して
□投稿者/ shu (96回)-(2010/10/13(Wed) 12:32:42)
No54301 (サンプラザ さん) に返信
> ※VB2008固有のソケットクラスは時間がないため、使用しない方針で進めています
と書いてありますが、結局実装に手間取っているなら使用した方がいいかと思います。

参考URL:
http://dobon.net/vb/dotnet/internet/tcpclientserver.html


Len -> Marshal.SizeOf
がいいかもしれないです


提示されたコードでは
SocketHandle(Index)
なんだか分かりません。
引用返信 編集キー/
■54304 / inTopicNo.3)  Re[1]: VB6⇒VB2008のソケット通信コンバージョンに関して
□投稿者/ 魔界の仮面弁士 (1864回)-(2010/10/13(Wed) 12:37:28)
No54301 (サンプラザ さん) に返信
> コネクト処理のConnectSocketメソッドでエラー番号:10038が返ってきます。
> ※VB2008固有のソケットクラスは時間がないため、使用しない方針で進めています
ConnectSocketメソッド というのは、
ソケット API の connect 関数の事でしょうか?


> 引数に問題があるかと思い、VB6とAPI宣言を比較していたのですが、
> VB2008初心者の私だけでは中々解決策が見つかりません。
幾つか注意点がありますが、ByVal と ByRef を間違えているのが最大の問題でしょう。


たとえば http://pcdn.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/winsock/
にある VB5 のサンプルでは、
 Public Declare Function connect Lib "wsock32.dll" _
  (ByVal s As Long, sName As sockaddr, ByVal namelen As Long) As Long
となっていますよね。
つまり『Function connect(ByVal Int32, ByRef sockaddr, ByVal Int32) As Int32』です。


それに対し、サンプラザ さんのコードは、
 Public Declare Function ConnectSocket Lib "wsock32.dll" Alias "connect" _
  (ByRef s As Integer, ByRef sName As sockaddr, ByRef namelen As Integer) As Integer
となっています。
つまり『Function connect(ByRef Int32, ByRef sockaddr, ByRef Int32) As Int32』です。


Function connect(ByVal Int32, ByRef sockaddr, ByVal Int32) As Int32 が必要な個所で
Function connect(ByRef Int32, ByRef sockaddr, ByRef Int32) As Int32 と宣言してしまえば、
正しい動作は望めないかと。
引用返信 編集キー/
■54309 / inTopicNo.4)  Re[2]: VB6⇒VB2008のソケット通信コンバージョンに関して
□投稿者/ サンプラザ (3回)-(2010/10/13(Wed) 13:10:57)
No54304 (魔界の仮面弁士 さん) に返信
> ■No54301 (サンプラザ さん) に返信
>>コネクト処理のConnectSocketメソッドでエラー番号:10038が返ってきます。
>>※VB2008固有のソケットクラスは時間がないため、使用しない方針で進めています
> ConnectSocketメソッド というのは、
> ソケット API の connect 関数の事でしょうか?

記述不足で申し訳ありません。
ソケット API の connect 関数の事です。



>>引数に問題があるかと思い、VB6とAPI宣言を比較していたのですが、
>>VB2008初心者の私だけでは中々解決策が見つかりません。
> 幾つか注意点がありますが、ByVal と ByRef を間違えているのが最大の問題でしょう。
>
>
> たとえば http://pcdn.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/winsock/
> にある VB5 のサンプルでは、
>  Public Declare Function connect Lib "wsock32.dll" _
>   (ByVal s As Long, sName As sockaddr, ByVal namelen As Long) As Long
> となっていますよね。
> つまり『Function connect(ByVal Int32, ByRef sockaddr, ByVal Int32) As Int32』です。
> それに対し、サンプラザ さんのコードは、
>  Public Declare Function ConnectSocket Lib "wsock32.dll" Alias "connect" _
>   (ByRef s As Integer, ByRef sName As sockaddr, ByRef namelen As Integer) As Integer
> となっています。
> つまり『Function connect(ByRef Int32, ByRef sockaddr, ByRef Int32) As Int32』です。
> Function connect(ByVal Int32, ByRef sockaddr, ByVal Int32) As Int32 が必要な個所で
> Function connect(ByRef Int32, ByRef sockaddr, ByRef Int32) As Int32 と宣言してしまえば、


魔界の仮面弁士様のおっしゃる通り、ByVal と ByRefを修正したところ、
正常にコネクト処理が開始され、ダミーサーバと通信する事ができました。
本当にありがとうございます。

残りのソケットAPI関数も宣言に誤りがないか、MSDNを参照しながら修正したいと思います。
再度ご質問させて頂くかもしれませんが、その際はよろしくお願いいたします。


解決済み
引用返信 編集キー/
■54310 / inTopicNo.5)  Re[2]: VB6⇒VB2008のソケット通信コンバージョンに関して
□投稿者/ サンプラザ (4回)-(2010/10/13(Wed) 13:14:44)
No54303 (shu さん) に返信
> Len -> Marshal.SizeOf
> がいいかもしれないです

上記箇所も修正し正常に動作しました。
shu様、本当にありがとうございます。


> 提示されたコードでは
> SocketHandle(Index)
> なんだか分かりません。

記述不足で申し訳ありません。

以下APIで取得したソケットハンドルが格納されます。

≪宣言部≫
 Public Declare Function CreateSocket Lib "wsock32.dll" Alias "socket" (ByVal af As Integer, ByVal lngType As Integer, ByVal protocol As Integer) As Integer

≪処理部≫
 SocketHandle(Index) = CreateSocket(AF_INET, SOCK_STREAM, 0)


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -