VB6遠端傳輸如何1對多??

Home Home
引用 | 編輯 w791212w
2008-09-15 20:24
樓主
推文 x0
我再作遠端傳輸的程式的時候一直沒辦 ..

訪客只能看到部份內容,免費 加入會員



獻花 x0
引用 | 編輯 三仙
2008-09-17 22:23
1樓
  
下面是引用w791212w於2008-09-15 20:24發表的 VB6遠端傳輸如何1對多??:
我再作遠端傳輸的程式的時候一直沒辦法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發表的 :
沒錯!~就三仙大大說的~動態去生成處理連線的物件
比方說你是用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
引用 | 編輯 三仙
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發表的 :
 

做法都是一樣的

如果要寫像msn那種ap
建議寫一個server端(db型態)
這樣也可以防止nat的問題

我是了過後...有一些些小問題...

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發表的 :
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
指令可以查查現在本機哪些被用了


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了喔??
  就是說對方使用的都是PORT 1024
  而我這邊要都不同是嗎??
  每一個人連進來我的PORT都要設定不同嗎??(如:第1個為1024.第2為1025.....以此類堆)
2.新增後的Winsock元件不要用的該怎麼移除??

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發表的 :
我又有1個疑問耶
關於VB6的Winsock元件
好像沒裝VB6的人打不開內涵Winsock元件的EXE檔
請問要怎麼處理??

連同執行檔附上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發表的 :
我給了對方"MSWINSCK.OCX"
但是卻出現下面著個問題

執行階段錯誤'400060'
對所要求的交易或要求而言,通訊協定(procol)不適合或連線狀態有誤
.......


40006的錯誤通常是程式碼在實際連線至通訊埠之前
Connect 沒有同步就試圖呼叫 SendData  或 GetData
建議你多寫一段等候 Connect 事件觸發之後
才進行呼叫SendData 或 GetData

獻花 x0
引用 | 編輯 三仙
2008-09-21 22:58
13樓
  
下面是引用w791212w於2008-09-20 15:55發表的 :



1.所以不同的電腦連進來要用不同的PORT了喔??
  就是說對方使用的都是PORT 1024
  而我這邊要都不同是嗎??
  每一個人連進來我的PORT都要設定不同嗎??(如:第1個為1024.第2為1025.....以此類堆)
2.新增後的Winsock元件不要用的該怎麼移除??


port 的 range 102465535

獻花 x0
引用 | 編輯 w791212w
2008-09-23 20:06
14樓
  
這個問題我處理好嚕 表情
結果是他沒連到我...

獻花 x0
引用 | 編輯 三仙
2008-09-24 00:19
15樓
  
下面是引用w791212w於2008-09-23 20:06發表的 :
這個問題我處理好嚕 表情
結果是他沒連到我...


其實從40006的錯誤提示
應該就可以知道方向
那是實際連線至通訊埠之前
Connect 沒有同步
所以只要改善此點
問題就可以解決了

獻花 x0