2017-04-01 215 views
0

我想用tcp連接通過互聯網發送文件。我的代碼處理這個IpV4好(creddits在這裏去http://technotif.com/creating-simple-tcpip-server-client-transfer-data-using-c-vb-net/,我只是改變小的東西,以糾正文件輸出) 我試圖用這與我的一個朋友,但他的路由器uteer垃圾,它不能轉發任何端口無論如何,甚至不會與upnp一起工作。它也被設置爲IpV6,據我所知,IPv6不再需要端口轉發,因爲每個設備都有自己的公共IP。通過IpV6發送文件

可悲的是我的程序不支持IPv6地址,而且我很難找到關於這個主題的任何信息。

這裏是我的代碼:

Public Class Form1 
Private nSockets As ArrayList 


Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
    Dim IPHost As IPHostEntry 
    IPHost = Dns.GetHostByName(Dns.GetHostName()) 
    lblStatus.Text = "My IP address is " + 
IPHost.AddressList(0).ToString() 
    nSockets = New ArrayList() 
    Dim thdListener As New Thread(New ThreadStart _ 
    (AddressOf listenerThread)) 
    thdListener.Start() 
End Sub 



Public Sub listenerThread() 

    Control.CheckForIllegalCrossThreadCalls = False 
    Dim tcpListener As New TcpListener(7080) 
    Dim handlerSocket As Socket 
    Dim thdstHandler As ThreadStart 
     Dim thdHandler As Thread 
     tcpListener.Start() 
     Do 
      handlerSocket = tcpListener.AcceptSocket() 
      If handlerSocket.Connected Then 
       lbConnections.Items.Add(
       handlerSocket.RemoteEndPoint.ToString() + 
       "connected.") 
       SyncLock (Me) 
        nSockets.Add(handlerSocket) 
       End SyncLock 
       thdstHandler = New ThreadStart(AddressOf _ 
       handlerThread) 
       thdHandler = New Thread(thdstHandler) 
       thdHandler.Start() 
      End If 
     Loop 
End Sub 

Public Sub handlerThread() 

     Dim handlerSocket As Socket 
     handlerSocket = nSockets(nSockets.Count - 1) 
    Dim networkStream As NetworkStream = New _ 
NetworkStream(handlerSocket) 
    Dim blockSize As Int16 = 16 
     Dim thisRead As Int16 
     Dim dataByte(blockSize) As Byte 
     SyncLock Me 
      ' Only one process can access the 
      ' same file at any given time 
      Dim fileStream As Stream 
      fileStream = File.OpenWrite("C:\Whatever.file") 
      While (True) 
       thisRead = networkStream.Read(dataByte, 
0, dataByte.Length) 
       fileStream.Write(dataByte, 0, thisRead) 
       If thisRead = 0 Then Exit While 
      End While 
      fileStream.Close() 
      networkStream.Close() 
     End SyncLock 
     lbConnections.Items.Add("File Written") 
    handlerSocket = Nothing 
End Sub 

我如何讓它支持IPv6?

忘了放在我的客戶端,我有什麼需要改變,使其工作?因爲即使對我的服務器進行了更改,它仍然沒有正確連接。

Private Sub Sendfile() 
    Dim filebuffer As Byte() 
    Dim fileStream As Stream 
    fileStream = File.OpenRead(tbFilename.Text) 
    ' Alocate memory space for the file 
    ReDim filebuffer(fileStream.Length) 
    fileStream.Read(filebuffer, 0, fileStream.Length) 
    ' Open a TCP/IP Connection and send the data 
    Dim clientSocket As New TcpClient(tbServer.Text, 7080) 
    Dim networkStream As NetworkStream 
    networkStream = clientSocket.GetStream() 
    networkStream.Write(filebuffer, 0, fileStream.Length) 
    networkStream.Close() 
End Sub 
+0

'Control.CheckForIllegalCrossThreadCalls = False' < - 這已經表明你做錯了什麼。檢查非法跨線程調用檢查是爲了阻止你做一些不好的事情,所以不應該禁用該檢查,而應該從頭開始。再次刪除該行並使您的代碼[**線程安全**](http://stackoverflow.com/documentation/vb.net/1913/threading/6235/performing-thread-safe-calls-using-control-調用#t = 201704011458227850227)。 –

+0

這是真的,我承認,這段代碼只是衝在一起:(我正在嘗試的東西,從來沒有與網絡代碼之前:)但謝謝你的信息。我想這也是原因,爲什麼有些線程在主窗體關閉後仍然保持打開狀態。 (它們在taskmanager進程列表中仍然可見)。或者是因爲另一個原因?如何正確中止主窗體關閉後的線程? – Alex

+0

爲什麼線程仍然活着的原因是因爲它們是前景線程。前臺線程被視爲應用程序的「重要」部分,每個進程在退出之前都必須手動關閉。 - 要修復它,請設置每個線程的[**'IsBackground'屬性**](https://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground(v = vs.110) .aspx)改爲「True」,然後再啓動它們。這將使他們在應用程序關閉時自動關閉。 –

回答

1

你的聽衆正在聽的IPv4地址0.0.0.0,這是默認的,當你只指定一個端口給聽者。

您需要使用TcpListener(IPAddress, Integer) overload並指定IPv6Any來偵聽IPv6地址。

Dim tcpListener As New TcpListener(IPAddress.IPv6Any, 7080) 

作爲一個側面說明,你應該寧可使用List(Of T)ArrayList。後者是無類型的,不像前者那樣爲.NET優化。

+0

謝謝,我無法證實,這對我有用,但我想這是我在客戶端的錯,忘了寫在問題中,我編了這個,也許你有足夠的空閒時間來看看它。 – Alex