引用 | 编辑
三仙
2008-09-17 22:23 |
1楼
▲ ▼ |
下面是引用w791212w于2008-09-15 20:24发表的 VB6远端传输如何1对多??: 建议用物件阵列的方式(可以Load 动态产生) 记得 port 不要冲突 x0 |
引用 | 编辑
overing
2008-09-18 01:48 |
2楼
▲ ▼ |
没错!~就三仙大大说的~动态去生成处理连线的物件
比方说你是用Socket去实作连线 就先建一个作监听连线用 一旦有连线进来就LOAD一个新的SOCKET 然后将倾听到的连线转交给新生成的去作处理 然后原来的SOCKET就释放连线继续倾听其他连线 大致上就是 在Form_Load的时候 iWinsocket(0).Protocol = sckTCPProtocol '指定使用TCP协定(比较省事) iWinsocket(0).LocalPort = 9999 '指定Server的请听Port iWinsocket(0).Listen 在iWinsock_ConnectionRequest的时候 使用ReDim Preserve 扩大阵列 (Preserve 是可以保留原阵列资料新增扩大的部分) Load新的iWinsock(counter) 然后iWinsock(counter).Accept requestID '将Listen到的连线转交给其他socket x0 |
引用 | 编辑
w791212w
2008-09-19 20:36 |
3楼
▲ ▼ |
下面是引用overing于2008-09-18 01:48发表的 : 那如果别人要连进来呢?? x0 |
引用 | 编辑
三仙
2008-09-19 21:13 |
4楼
▲ ▼ |
下面是引用w791212w于2008-09-19 20:36发表的 : 做法都是一样的 如果要写像msn那种ap 建议写一个server端(db型态) 这样也可以防止nat的问题 x0 |
引用 | 编辑
w791212w
2008-09-19 21:28 |
5楼
▲ ▼ |
下面是引用三仙于2008-09-19 21:13发表的 : 我是了过后...有一些些小问题... server端 '--------------------------------------------------------------------------------------------------------- Dim wk(1000) As Integer Dim win As Integer Private Sub Form_Load() win = 0 Winsock1(win).LocalPort = 1001 Label1.Caption = "已断开连线!" Winsock1(win).Listen End Sub Private Sub Winsock1_Close(Index As Integer) Winsock1(Index).Close Label1.Caption = "已经连线 !" wk(Index) = 0 Print Index; " 以断线" End Sub Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long) For i = 0 To win If wk(i) = 0 Then Winsock1(i).Close Label1.Caption = "已经连线 !" wk(i) = 1 Print i; " 以连线" Winsock1(i).Accept requestID win = win + 1 Load Winsock1(win) Winsock1(win).LocalPort = 1001 Winsock1(win).Listen End If Next i End Sub Private Sub Winsock1_Error(Index As Integer, ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) Winsock1(Index).Close Label1.Caption = "已经连线 !" wk(Index) = 0 Print Index; " 以断线" End Sub '--------------------------------------------------------------------------------------------------------- 连结端 '--------------------------------------------------------------------------------------------------------- Private Sub Command1_Click() '连线 Winsock1.Close Winsock1.RemoteHost = Text1.Text Winsock1.RemotePort = 1001 Label1.Caption = "连线中 ..." Winsock1.Connect End Sub Private Sub Command2_Click() '断开 Winsock1.Close Label1.Caption = "已断开连线!" End Sub Private Sub Form_Load() Winsock1.Close Winsock1.RemotePort = 1001 Label1.Caption = "断开 ..." Winsock1.Listen End Sub Private Sub Winsock1_Close() Winsock1.Close Label1.Caption = "已断开连线!" End Sub Private Sub Winsock1_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) Winsock1.Close Label1.Caption = "已断开连线!" End Sub '--------------------------------------------------------------------------------------------------------- 我先按连线(Command1),后按断开(Command2),在按连线(Command1) 红色字那他说地址已用过我该怎么处理@@? x0 |
引用 | 编辑
overing
2008-09-20 11:33 |
6楼
▲ ▼ |
Listen的Socket最好固定在一个index(建议啦)
然后连进来之后的要转交给其他port作处理 不然1001已经被先前连进来的占住了当然没办法再Listen 还有就是最好可以在From_Unload那里加个socket.Close 这样表单关掉的时候才能确保port有释放掉 还有就是建议PORT从1024之后开始用吧!~ 已知标准PORT http://www.chu.edu.tw/~chunpo/solaris/tech/docs/port.html 尽量避开常用的标准PORT 挑一段空的来用 netstat -ano 指令可以查查现在本机哪些被用了 x0 |
引用 | 编辑
w791212w
2008-09-20 15:55 |
7楼
▲ ▼ |
下面是引用overing于2008-09-20 11:33发表的 : 1.所以不同的电脑连进来要用不同的PORT了喔?? 就是说对方使用的都是PORT 1024 而我这边要都不同是吗?? 每一个人连进来我的PORT都要设定不同吗??(如:第1个为1024.第2为1025.....以此类堆) 2.新增后的Winsock元件不要用的该怎么移除?? x0 |
引用 | 编辑
overing
2008-09-20 17:45 |
8楼
▲ ▼ |
下面是引用w791212w于2008-09-20 15:55发表的 : 1.没错!~ 把port比喻作港口好了 Server国家要同时跟其他Client国家进行贸易(资料交换) Client们只须要用一个自己有空闲的港口即可 而Server要"同时"跟各国贸易当然要为每一个国家设立一个专属的入港(port) 除非你不是"同时"要跟各个Client作贸易... 通常Server国会开设一个固定的"入港申请处" (固定的port) 这样每个Client国只需要记住入港申请处的port即可 而不必每次要贸易就须要询问一次Server国家他该从哪个port进入 当有Client连上入港申请处就会配给一个专属的port(将连线转交给其他socket) 而入港申请处就继续恢复到等待下个国家的状态 Java方面的作法是利用ServerSocket.accept()将连线转交给Thread+Socket(Client)的方式 VB的话应该可以在ConnectionRequest的时候将requestID交给不同的socket(Index).Accept来做... 如果你不在乎Client每次执行都须要先向Server询问他该从哪个port进入 或是规划上的Client量本来就不多了 那么你现在的方式就可以了... 2.没有要用(已经Close)的socket有两种方式处理 * 留着给之后的连线用 * 使用 Unload 将之卸载 留着的好处是可以让下次不用在建立新的socket 不过要自己稍微写一下分配socket的演算法 Unload掉是对资源使用量比较健康(?) 不过也是得考虑一下index的排列方式 不然Server开久一点idx一直+++下去也会暴 x0 |
引用 | 编辑
w791212w
2008-09-20 20:28 |
9楼
▲ ▼ |
我又有1个疑问耶
关于VB6的Winsock元件 好像没装VB6的人打不开内涵Winsock元件的EXE档 请问要怎么处理?? x0 |
引用 | 编辑
overing
2008-09-20 20:31 |
10楼
▲ ▼ |
下面是引用w791212w于2008-09-20 20:28发表的 : 连同执行档附上Winsock的来源物件档 mswinsck.ocx 给对方 通常在 %SystemRoot%\system32\mswinsck.ocx x0 |
引用 | 编辑
w791212w
2008-09-21 18:35 |
11楼
▲ ▼ |
图 1. 我给了对方"MSWINSCK.OCX" 但是却出现下面着个问题 执行阶段错误'400060' 对所要求的交易或要求而言,通讯协定(procol)不适合或连线状态有误 请问我程式码哪里出错了?? sever -------------------------------------------------------------------------------- Dim wk(1000) As Integer Dim win As Integer Dim tempne As Integer Dim tempstr As String Dim account, account_sever As String Dim password, password_sever As String Private Sub Form_Load() win = 0 Winsock1(win).LocalPort = 1024 Label1(win).Caption = "已断开连线!" Winsock1(win).Listen End Sub Private Sub Winsock1_Close(Index As Integer) Winsock1(Index).Close Label1(Index).Caption = "已断开连线!" wk(Index) = 0 End Sub Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long) For i = 0 To win If wk(i) = 0 Then Winsock1(i).Close Label1(i).Caption = "已经连线 !" wk(i) = 1 Winsock1(i).Accept requestID wink = 0 For k = 0 To 1000 If wk(k) = 1 Then wink = wink + 1 Next k If wink = win + 1 Then win = win + 1 Load Winsock1(win) Load Label1(win) Load Label2(win) Label1(win).Visible = True Label2(win).Visible = True Label1(win).Caption = "" Label2(win).Caption = "" Label1(win).Left = Label1(win - 1).Left Label1(win).Top = Label1(win - 1).Top + 240 Label2(win).Left = Label2(win - 1).Left Label2(win).Top = Label2(win - 1).Top + 240 Winsock1(win).LocalPort = 1024 Winsock1(win).Listen End If Exit For End If Next i End Sub Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long) Winsock1(Index).GetData tempstr Label2(Index).Caption = tempstr tempne = Index find = Mid(tempstr, 1, 2) If find = "ap" Then Call test_ap End Sub Private Sub Winsock1_Error(Index As Integer, ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) Winsock1(Index).Close Label1(Index).Caption = "已断开连线!" wk(Index) = 0 End Sub Sub test_ap() Dim result_end As String find_a = InStr(tempstr, "a=") find_p = InStr(tempstr, "p=") account = Mid(tempstr, find_a + 2, Len(tempstr) - find_p - 1) password = Mid(tempstr, find_p + 2, Len(tempstr)) Print account Print password Open "at&pd\player.ap" For Input As #1 Do While Not EOF(1) Input #1, account_sever Input #1, password_sever If account_sever = account Then If password_sever = password Then result_end = "test_ap_OK" Exit Do End If End If result_end = "test_ap_NO" Loop Winsock1(tempne).SendData result_end Close #1 End Sub 用户端 ------------------------------------------------------------------------------------------------ Private Sub Command1_Click() ww = "ap" & "a=" & Text1.Text & "p=" & Text2.Text Winsock1.SendData ww End Sub Private Sub Form_Load() Winsock1.Close Label3.Caption = "已断开连线!" If Text3.Text = "" Then Label3.Caption = "请输入主机名称!" Exit Sub End If Winsock1.RemoteHost = Text3.Text Winsock1.RemotePort = 1024 Winsock1.Connect End Sub Private Sub Timer1_Timer() Winsock1.Close Label3.Caption = "已断开连线!" If Text3.Text = "" Then Label3.Caption = "请输入主机名称!" Exit Sub End If Winsock1.RemoteHost = Text3.Text Winsock1.RemotePort = 1024 Winsock1.Connect End Sub Private Sub Winsock1_Close() Winsock1.Close Timer1.Enabled = True Label3.Caption = "已断开连线!" End Sub Private Sub Winsock1_Connect() Label3.Caption = "连线中 ..." Timer1.Enabled = False End Sub Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Dim strData As String Winsock1.GetData strData If strData = "test_ap_OK" Then Label3.Caption = "登入成功!" If strData = "test_ap_NO" Then Label3.Caption = "登入失败!" End Sub Private Sub Winsock1_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) Label3.Caption = "已断开连线!" Label3.Caption = Description Winsock1.Close End Sub x0 |
引用 | 编辑
三仙
2008-09-21 22:48 |
12楼
▲ ▼ |
下面是引用w791212w于2008-09-21 18:35发表的 : 40006的错误通常是程式码在实际连线至通讯埠之前 Connect 没有同步就试图呼叫 SendData 或 GetData 建议你多写一段等候 Connect 事件触发之后 才进行呼叫SendData 或 GetData x0 |