创建TCP连接时,系统自动分配的端口,怎么样获取这个端口呢
本帖最后由 破帽遮颜 于 2010-8-1 14:56 编辑创建TCP连接,端口号为0时,系统会自动分配一个空闲端口,使用什么方法可以获取这个端口号呢?
getsockname?
悬赏贴http://www.autoitx.com/thread-17303-1-1.html#include 'array.au3'
TCPStartup()
Global Const $__TCP_WINDOW = GUICreate('')
Global $hWs2_32 = -1
_TCP_Server_Create(0, '0.0.0.0')
MsgBox(4096, '', '现在服务端创建的TCP连接使用的端口是?该如何获取呢?')
While 1
Sleep(100)
WEnd
Func _TCP_Server_Create($iPort, $sIP = "0.0.0.0")
$hListenSocket = _ASocket()
_ASockSelect($hListenSocket, $__TCP_WINDOW, 0x0400, 8)
_ASockListen($hListenSocket, $sIP, $iPort)
Return $hListenSocket
EndFunc ;==>_TCP_Server_Create
Func _ASocket($iAddressFamily = 2, $iType = 1, $iProtocol = 6)
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $hSocket = DllCall($hWs2_32, "uint", "socket", "int", $iAddressFamily, "int", $iType, "int", $iProtocol)
If @error Then
SetError(1, @error)
Return -1
EndIf
If $hSocket = -1 Then
SetError(2, _WSAGetLastError())
Return -1
EndIf
Return $hSocket
EndFunc ;==>_ASocket
Func _ASockSelect($hSocket, $hWnd, $uiMsg, $iEvent)
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $iRet = DllCall($hWs2_32, "int", "WSAAsyncSelect", "uint", $hSocket, "hwnd", $hWnd, "uint", $uiMsg, "int", $iEvent)
If @error Then
SetError(1, @error)
Return False
EndIf
Return True
EndFunc ;==>_ASockSelect
Func _ASockListen($hSocket, $sIP, $uiPort, $iMaxPending = 5)
Local $iRet
Local $stAddress
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
$stAddress = __SockAddr($sIP, $uiPort)
If @error Then
SetError(@error, @extended)
Return False
EndIf
$iRet = DllCall($hWs2_32, "int", "bind", "uint", $hSocket, "ptr", DllStructGetPtr($stAddress), "int", DllStructGetSize($stAddress))
If @error Then
SetError(3, @error)
Return False
EndIf
If $iRet <> 0 Then
$stAddress = 0
SetError(4, _WSAGetLastError())
Return False
EndIf
$iRet = DllCall($hWs2_32, "int", "listen", "uint", $hSocket, "int", $iMaxPending)
If @error Then
SetError(5, @error)
Return False
EndIf
If $iRet <> 0 Then
$stAddress = 0
SetError(6, _WSAGetLastError())
Return False
EndIf
Return True
EndFunc ;==>_ASockListen
Func __SockAddr($sIP, $iPort, $iAddressFamily = 2)
Local $iRet
Local $stAddress
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
$stAddress = DllStructCreate("short;ushort;uint;char")
If @error Then
SetError(1, @error)
Return False
EndIf
DllStructSetData($stAddress, 1, $iAddressFamily)
$iRet = DllCall($hWs2_32, "ushort", "htons", "ushort", $iPort)
DllStructSetData($stAddress, 2, $iRet)
$iRet = DllCall($hWs2_32, "uint", "inet_addr", "str", $sIP)
If $iRet = 0xffffffff Then
$stAddress = 0
SetError(2, _WSAGetLastError())
Return False
EndIf
DllStructSetData($stAddress, 3, $iRet)
Return $stAddress
EndFunc ;==>__SockAddr
Func _WSAGetLastError()
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $iRet = DllCall($hWs2_32, "int", "WSAGetLastError")
If @error Then
ConsoleWrite("+> _WSAGetLastError(): WSAGetLastError() failed. Script line number: " & @ScriptLineNumber & @CRLF)
SetExtended(1)
Return 0
EndIf
Return $iRet
EndFunc ;==>_WSAGetLastError 希望有高手指点 Up~~~~~~~~~~~~~~~~~~~~~ 能指定端口吗,
我试过UDP发送数据,可以指定远程的端口号,但不能指定本地发送数据的端口号 能指定端口吗,
我试过UDP发送数据,可以指定远程的端口号,但不能指定本地发送数据的端口号
auto 发表于 2010-7-30 23:16 http://www.autoitx.com/images/common/back.gif
指定端口就失去这个问题的意义了。
呵呵 先具体解释下端口为0是怎样?
你所说的TCP连接是指TCPListen?TCPConnect?
or??? 本帖最后由 破帽遮颜 于 2010-8-1 14:52 编辑
#include 'array.au3'
TCPStartup()
Global Const $__TCP_WINDOW = GUICreate('')
Global $hWs2_32 = -1
_TCP_Server_Create(0, '0.0.0.0')
MsgBox(4096, '', '现在服务端创建的TCP连接使用的端口是?该如何获取呢?')
While 1
Sleep(100)
WEnd
Func _TCP_Server_Create($iPort, $sIP = "0.0.0.0")
$hListenSocket = _ASocket()
_ASockSelect($hListenSocket, $__TCP_WINDOW, 0x0400, 8)
_ASockListen($hListenSocket, $sIP, $iPort)
Return $hListenSocket
EndFunc ;==>_TCP_Server_Create
Func _ASocket($iAddressFamily = 2, $iType = 1, $iProtocol = 6)
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $hSocket = DllCall($hWs2_32, "uint", "socket", "int", $iAddressFamily, "int", $iType, "int", $iProtocol)
If @error Then
SetError(1, @error)
Return -1
EndIf
If $hSocket = -1 Then
SetError(2, _WSAGetLastError())
Return -1
EndIf
Return $hSocket
EndFunc ;==>_ASocket
Func _ASockSelect($hSocket, $hWnd, $uiMsg, $iEvent)
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $iRet = DllCall($hWs2_32, "int", "WSAAsyncSelect", "uint", $hSocket, "hwnd", $hWnd, "uint", $uiMsg, "int", $iEvent)
If @error Then
SetError(1, @error)
Return False
EndIf
Return True
EndFunc ;==>_ASockSelect
Func _ASockListen($hSocket, $sIP, $uiPort, $iMaxPending = 5)
Local $iRet
Local $stAddress
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
$stAddress = __SockAddr($sIP, $uiPort)
If @error Then
SetError(@error, @extended)
Return False
EndIf
$iRet = DllCall($hWs2_32, "int", "bind", "uint", $hSocket, "ptr", DllStructGetPtr($stAddress), "int", DllStructGetSize($stAddress))
If @error Then
SetError(3, @error)
Return False
EndIf
If $iRet <> 0 Then
$stAddress = 0
SetError(4, _WSAGetLastError())
Return False
EndIf
$iRet = DllCall($hWs2_32, "int", "listen", "uint", $hSocket, "int", $iMaxPending)
If @error Then
SetError(5, @error)
Return False
EndIf
If $iRet <> 0 Then
$stAddress = 0
SetError(6, _WSAGetLastError())
Return False
EndIf
Return True
EndFunc ;==>_ASockListen
Func __SockAddr($sIP, $iPort, $iAddressFamily = 2)
Local $iRet
Local $stAddress
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
$stAddress = DllStructCreate("short;ushort;uint;char")
If @error Then
SetError(1, @error)
Return False
EndIf
DllStructSetData($stAddress, 1, $iAddressFamily)
$iRet = DllCall($hWs2_32, "ushort", "htons", "ushort", $iPort)
DllStructSetData($stAddress, 2, $iRet)
$iRet = DllCall($hWs2_32, "uint", "inet_addr", "str", $sIP)
If $iRet = 0xffffffff Then
$stAddress = 0
SetError(2, _WSAGetLastError())
Return False
EndIf
DllStructSetData($stAddress, 3, $iRet)
Return $stAddress
EndFunc ;==>__SockAddr
Func _WSAGetLastError()
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $iRet = DllCall($hWs2_32, "int", "WSAGetLastError")
If @error Then
ConsoleWrite("+> _WSAGetLastError(): WSAGetLastError() failed. Script line number: " & @ScriptLineNumber & @CRLF)
SetExtended(1)
Return 0
EndIf
Return $iRet
EndFunc ;==>_WSAGetLastError 帮顶下,太深奥了 开始监听或者连接后,你你设置的0 在读出来,就可以得到系统赋予的端口号.
getsockname(........)
$stAddress里的htons _MakeLong 为什么不用位移 *10000和左移4位,效率应该不同.
没有线程池甚至连工作线程都没有.
你就没有试试启动1000个客户端.
CONNECT后立即CLOSE,你的服务端还能正常工作吗?
redim的效率非常低,而且内存泄漏严重.
这种方法可能导致服务端不能正常长时间运行.
$iRet = _WSAGetLastError()
If $iRet = 10035 Then
Return True
EndIf
SetExtended(1)
Return True
这段更让人看不懂.
既然WSAGetLastError不等于0也不等于WSAEISCONN (10056) ,顶多也只能说明正在连接中.
没看到有设置CONNECT超时,那么你CONN时,是不是整个程序就要等待6秒左右的无法响应?(如果IP不存在.)
仅提下建议,别介意. 其实我很想看到牛人,能用AU3这种单线程 写出 SOCKET服务,所以说了这么多. 指定端口就失去这个问题的意义了。
呵呵
破帽遮颜 发表于 2010-7-31 00:40 http://www.autoitx.com/images/common/back.gif
是我刚好有这个需求,需要指端口来发送数据 深奥,还未接触,,,,加油,努力 _MakeLong 为什么不用位移 *10000和左移4位,效率应该不同.
没有线程池甚至连工作线程都没有.
你就没有试 ...
akmm88 发表于 2010-7-31 10:15 http://www.autoitx.com/images/common/back.gif
呵呵,谢谢回复。
这个UDF并不是我写的。我只是针对系统随机分配端口,所以放上来一个例子。
你能帮忙解决这个问题吗?拜托了。^_^ 回复 7# 破帽遮颜
这个很漂亮~~ 没弄明白,要获取的是sever的端口,还是Client的端口?
页:
[1]
2