2017-04-01 164 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