引用 | 編輯
三仙
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 |