'------------------------------------------------------------------------------------
'基于TCP的网络信息传输
' TNT
' 2008-1-7
'一个礼拜写一点东西出来,不为别的只为学习。
' 我一定会坚持下来的!
'------------------------------------------------------------------------------------
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Public Class Form1
Private s As SocketTCP
Private thread As Thread
Private RemoteIP As String
Private RemotePort As String
Private LocalIP As String
Private LocalPort As String
Private Sub Listen()
s.Listen()
End Sub
Private Sub receive(ByVal message As String)
Me.RTB.AppendText(message)
End Sub
Private Sub send(ByVal message As String)
s.Send(message)
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
s.Close()
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'vs05在新加的功能窗体控件的线程安全,即只有创建控件的线程才可以对线程操作。
'但是很多时候我们需要跨线程操作例如本例,下面是最简单的处理方法。
CheckForIllegalCrossThreadCalls = False '允许跨线程操作窗体
s = New SocketTCP(AddressOf receive, True)
AddHandler s.EventReceiveMessage, AddressOf receive
thread = New Thread(AddressOf s.Receive)
thread.Start()
End Sub
Private Sub btnlisten_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnlisten.Click
Listen()
End Sub
Private Sub btnsend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnsend.Click
send("success" + vbCrLf)
End Sub
End Class
Public Class SocketTCP
'本地信息
Private l_IP As String 'IP
Private l_Port As String '通迅端口
Private l_ENP As IPEndPoint '终端
'远端信息
Private m_IP As String 'IP
Private m_Port As String '通迅端口
Private m_ENP As IPEndPoint '终端
Private s_TransfSize As TransfKind = TransfKind.small '传送信息的大小
Private s As Socket '用于侦听的套接字
Private sConnect As Socket '用于连接的套接字
Private thread As Thread '用于接收信息的线程
Private ReceiveMessage As DelegateReceiveMessage '委托变量
Private s_IsServer As Boolean '是不是做为服务器
Private s_IsConnectting As Boolean '是不是已经连接上
'传送信息的大小,理论上应该对传输速度有影响
Public Enum TransfKind
big
middle
small
End Enum
#Region "属性"
''' <summary>
''' 本地IP
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property LocalIP() As String
Get
Return l_IP
End Get
Set(ByVal value As String)
l_IP = value
End Set
End Property
''' <summary>
''' 本地PORT
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property LocalPort() As String
Get
Return l_Port
End Get
Set(ByVal value As String)
l_Port = value
End Set
End Property
''' <summary>
''' 远端IP
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property RemoteIP() As String
Get
Return m_IP
End Get
Set(ByVal value As String)
m_IP = value
End Set
End Property
''' <summary>
''' 远端PORT
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property RemotePort() As String
Get
Return m_Port
End Get
Set(ByVal value As String)
m_Port = value
End Set
End Property
''' <summary>
''' 一次传输的数据量
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks>有三种情况big-1024*5,middle-1024,small -128</remarks>
Public Property TransfSize() As TransfKind
Get
Return s_TransfSize
End Get
Set(ByVal value As TransfKind)
s_TransfSize = value
End Set
End Property
''' <summary>
''' 选择服务类型
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property IsServer() As Boolean
Get
Return s_IsServer
End Get
Set(ByVal value As Boolean)
s_IsServer = value
End Set
End Property
''' <summary>
''' 判断是不是处于连接状态
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property IsConnectting() As Boolean
Get
Return s_IsConnectting
End Get
Set(ByVal value As Boolean)
s_IsConnectting = value
End Set
End Property
#End Region
#Region "事件"
Public Event EventReceiveMessage(ByVal message As String)
Public Delegate Sub DelegateReceiveMessage(ByVal message As String)
#End Region
#Region "构造方法"
Sub New(ByVal d As DelegateReceiveMessage, ByVal server As Boolean)
'用于委托
ReceiveMessage = d
'类型
s_IsServer = server
'负责连接的套接字
sConnect = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
'设置并启动计时器
setTimer()
End Sub
Sub New(ByVal IP As String, ByVal Port As String, ByVal d As DelegateReceiveMessage, ByVal server As Boolean)
m_IP = IP
m_Port = Port
'终端
Try
m_ENP = New IPEndPoint(IPAddress.Parse(m_IP), Convert.ToInt32(m_Port))
Catch e As Exception
messageshow("终端设置错误!!!")
End Try
'用于委托
ReceiveMessage = d
'类型
s_IsServer = server
sConnect = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
'设置并启动计时器
setTimer()
End Sub
#End Region
#Region "方法"
''' <summary>
''' 设置本地信息
''' </summary>
''' <remarks></remarks>
Private Sub SetLocalInfo()
If l_IP = "" Then
l_IP = Dns.Resolve(Dns.GetHostName()).AddressList(0).ToString
End If
If l_Port = "" Then
l_Port = "10000"
End If
'本地终端
l_ENP = New IPEndPoint(IPAddress.Parse(l_IP), Convert.ToInt32(l_Port))
End Sub
Public Sub SetRemoteEnp()
If m_IP = "" Then m_IP = "127.0.0.1"
If m_Port = "" Then m_Port = "10000"
'远端的终端
Try
m_ENP = New IPEndPoint(IPAddress.Parse(m_IP), Convert.ToInt32(m_Port))
Catch e As Exception
messageshow("终端设置错误!!!")
End Try
End Sub
''' <summary>
''' 侦听
''' </summary>
''' <remarks>如果是服务器则执行此方法</remarks>
Public Sub Listen()
'获取本地终端
SetLocalInfo()
'定义负责侦听的套接字
s = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Try
Application.DoEvents()
s.Bind(l_ENP)
s.Listen(20)
'建立连接
sConnect = s.Accept()
'启动线程接收信息
thread = New Thread(AddressOf Receive)
thread.Start()
Catch e As Exception
messageshow(e.ToString)
End Try
End Sub
''' <summary>
''' 连接服务器
''' </summary>
''' <remarks>为客户端用</remarks>
Public Sub Connect()
If m_ENP Is Nothing Then
SetRemoteEnp()
Else
Try
sConnect.Connect(m_ENP)
Catch ex As SocketException
s_IsConnectting = False
messageshow(ex.ToString)
End Try
End If
End Sub
''' <summary>
''' 接收信息
''' </summary>
''' <remarks>通过触发事件或用委托来返回信息</remarks>
Public Sub Receive()
Dim size As Integer
Select Case s_TransfSize
Case TransfKind.big
size = 1024 * 5
Case TransfKind.middle
size = 1024
Case TransfKind.small
size = 128
End Select
Try
If sConnect.Connected Then
While True
Dim receiveByte(size) As Byte
sConnect.Receive(receiveByte, receiveByte.Length, 0)
Dim receivestr = System.Text.Encoding.BigEndianUnicode.GetString(receiveByte)
'重点,返回信息
ReceiveMessage(receivestr)
'RaiseEvent EventReceiveMessage(receivestr)
End While
End If
Catch ex As SocketException
messageshow(ex.ToString)
End Try
End Sub
''' <summary>
''' 发送信息
''' </summary>
''' <param name="message"></param>
''' <remarks></remarks>
Public Sub Send(ByVal message As String)
Dim size As Integer
Select Case s_TransfSize
Case TransfKind.big
size = 1024 * 5
Case TransfKind.middle
size = 1024
Case TransfKind.small
size = 128
End Select
Dim sendbyte() As Byte = System.Text.Encoding.BigEndianUnicode.GetBytes(message.ToCharArray())
sConnect.Send(sendbyte)
End Sub
''' <summary>
''' 关闭连接
''' </summary>
''' <remarks></remarks>
Public Sub Close()
thread.Abort()
sConnect.Close()
If s_IsServer Then s.Close()
End Sub
#Region "计时器"
'用来判断连接状态
Private myTimer As New System.Windows.Forms.Timer()
Private Sub setTimer()
myTimer.Interval = 1000
myTimer.Enabled = True
'myTimer.Start()
AddHandler myTimer.Tick, AddressOf TimerEventProcessor
End Sub
Private Sub TimerEventProcessor(ByVal myObject As Object, ByVal myEventArgs As EventArgs)
s_IsConnectting = sConnect.Connected
Debug.Print("success")
End Sub
#End Region
'显示设置
Private Sub messageshow(ByVal message As String)
MessageBox.Show(message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
End Sub
#End Region
End Class