socket编程文件传输_winsock文件传输编程
1.C语言编写TCP的文件传输
2.winsock文件传输问题
3.如何用VB实现数据文件传输? 最好有代码和窗口或者注明有哪些控件
4.怎么用 Winsock 发送大于1M以上的数据
5.vb怎么实现远程文件传输
6.vb6.0怎么用winsock发送大文件
7.VB如何实现传输语音和文件,我想做个聊天工具
我这里有个无窗体的winsock模块 , 35k大 ,这里放不下,需要完整的话再联系我.以下是其中开头部分:
'Visual Basic 4.0 and above winsock declares and functions modules
'requires a msghook for async methods and functions. This declares
'file was originally oained from the alt.winsock.programming news
'group, alot has been added and modified since that time. However I
'would like to credit the people on that newsgroup for the information
'they contributed, and now I pass it back...
'
'NOTES:
' I hen't been able to get the WSAAsyncGetXbyY functions to work properly
'under windows95(tm) aside from that ALL functions "SHOULD" work just fine.
'any questions about this file may be posted to alt.winsock.programming
' Topaz..
'
Option Explicit
'windows declares here
#If Win16 Then
Declare Function PostMessage Lib "User" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, lParam As Any) As Integer
Declare Sub MemCopy Lib "Kernel" Alias "hmemcpy" (Dest As Any, Src As Any, ByVal cb&)
Declare Function lstrlen Lib "Kernel" (ByVal lpString As Any) As Integer
#ElseIf Win32 Then
Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Sub MemCopy Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal cb&)
Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Any) As Long
#End If
'WINSOCK DEFINES START HERE
'not same
Global Const FD_SETSIZE = 64
Type fd_set
fd_count As Integer
fd_array(FD_SETSIZE) As Integer
End Type
'same
Type timeval
tv_sec As Long
tv_usec As Long
End Type
Type HostEnt
h_name As Long
h_aliases As Long
h_addrtype As Integer
h_length As Integer
h_addr_list As Long
End Type
Const hostent_size = 16
Type servent
s_name As Long
s_aliases As Long
s_port As Integer
s_proto As Long
End Type
Const servent_size = 14
Type protoent
p_name As Long
p_aliases As Long
p_proto As Integer
End Type
Const protoent_size = 10
Global Const IPPROTO_TCP = 6
Global Const IPPROTO_UDP = 17
Global Const INADDR_NONE = &HFFFFFFFF
Global Const INADDR_ANY = &H0
Type sockaddr
sin_family As Integer
sin_port As Integer
sin_addr As Long
sin_zero As String * 8
End Type
Const sockaddr_size = 16
Dim saZero As sockaddr
Global Const WSA_DESCRIPTIONLEN = 256
Global Const WSA_DescriptionSize = WSA_DESCRIPTIONLEN + 1
Global Const WSA_SYS_STATUS_LEN = 128
Global Const WSA_SysStatusSize = WSA_SYS_STATUS_LEN + 1
Type WSADataType
wVersion As Integer
wHighVersion As Integer
szDescription As String * WSA_DescriptionSize
szSystemStatus As String * WSA_SysStatusSize
iMaxSockets As Integer
iMaxUdpDg As Integer
lpVendorInfo As Long
End Type
Global Const INVALID_SOCKET = -1
Global Const SOCKET_ERROR = -1
Global Const SOCK_STREAM = 1
Global Const SOCK_DGRAM = 2
Global Const MAXGETHOSTSTRUCT =
Global Const AF_INET = 2
Global Const PF_INET = 2
Type LingerType
l_onoff As Integer
l_linger As Integer
End Type
#If Win32 Then
Global Const SOL_SOCKET = &HFFFF&
Global Const SO_LINGER = &H80&
Global Const FD_READ = &H1&
Global Const FD_WRITE = &H2&
Global Const FD_OOB = &H4&
Global Const FD_ACCEPT = &H8&
Global Const FD_CONNECT = &H10&
Global Const FD_CLOSE = &H20&
#Else
Global Const SOL_SOCKET = &HFFFF
Global Const SO_LINGER = &H80
Global Const FD_READ = &H1
Global Const FD_WRITE = &H2
Global Const FD_OOB = &H4
Global Const FD_ACCEPT = &H8
Global Const FD_CONNECT = &H10
Global Const FD_CLOSE = &H20
#End If
'SOCKET FUNCTIONS
#If Win16 Then
'SOCKET FUNCTIONS
Declare Function accept Lib "Winsock.dll" (ByVal s As Integer, addr As sockaddr, addrlen As Integer) As Integer
Declare Function bind Lib "Winsock.dll" (ByVal s As Integer, addr As sockaddr, ByVal namelen As Integer) As Integer
Declare Function closesocket Lib "Winsock.dll" (ByVal s As Integer) As Integer
Declare Function connect Lib "Winsock.dll" (ByVal s As Integer, addr As sockaddr, ByVal namelen As Integer) As Integer
Declare Function ioctlsocket Lib "Winsock.dll" (ByVal s As Integer, ByVal cmd As Long, argp As Long) As Integer
Declare Function getpeername Lib "Winsock.dll" (ByVal s As Integer, sname As sockaddr, namelen As Integer) As Integer
Declare Function getsockname Lib "Winsock.dll" (ByVal s As Integer, sname As sockaddr, namelen As Integer) As Integer
Declare Function getsockopt Lib "Winsock.dll" (ByVal s As Integer, ByVal level As Integer, ByVal optname As Integer, ByVal optval As String, optlen As Integer) As Integer
Declare Function htonl Lib "Winsock.dll" (ByVal hostlong As Long) As Long
Declare Function htons Lib "Winsock.dll" (ByVal hostshort As Integer) As Integer
Declare Function inet_addr Lib "Winsock.dll" (ByVal cp As String) As Long
Declare Function inet_ntoa Lib "Winsock.dll" (ByVal inn As Long) As Long
Declare Function listen Lib "Winsock.dll" (ByVal s As Integer, ByVal backlog As Integer) As Integer
Declare Function ntohl Lib "Winsock.dll" (ByVal netlong As Long) As Long
Declare Function ntohs Lib "Winsock.dll" (ByVal netshort As Integer) As Integer
Declare Function recv Lib "Winsock.dll" (ByVal s As Integer, buf As Any, ByVal buflen As Integer, ByVal flags As Integer) As Integer
Declare Function recvfrom Lib "Winsock.dll" (ByVal s As Integer, ByVal buf As String, ByVal buflen As Integer, ByVal flags As Integer, from As sockaddr, fromlen As Integer) As Integer
Declare Function ws_select Lib "Winsock.dll" Alias "select" (ByVal nfds As Integer, readfds As fd_set, writefds As fd_set, exceptfds As fd_set, timeout As timeval) As Integer
Declare Function send Lib "Winsock.dll" (ByVal s As Integer, buf As Any, ByVal buflen As Integer, ByVal flags As Integer) As Integer
Declare Function sendto Lib "Winsock.dll" (ByVal s As Integer, buf As Any, ByVal buflen As Integer, ByVal flags As Integer, to_addr As sockaddr, ByVal tolen As Integer) As Integer
Declare Function setsockopt Lib "Winsock.dll" (ByVal s As Integer, ByVal level As Integer, ByVal optname As Integer, optval As Any, ByVal optlen As Integer) As Integer
Declare Function ShutDown Lib "Winsock.dll" Alias "shutdown" (ByVal s As Integer, ByVal how As Integer) As Integer
Declare Function socket Lib "Winsock.dll" (ByVal af As Integer, ByVal s_type As Integer, ByVal protocol As Integer) As Integer
'DATABASE FUNCTIONS
Declare Function gethostbyaddr Lib "Winsock.dll" (addr As Long, ByVal addr_len As Integer, ByVal addr_type As Integer) As Long
Declare Function gethostbyname Lib "Winsock.dll" (ByVal host_name As String) As Long
Declare Function gethostname Lib "Winsock.dll" (ByVal host_name As String, ByVal namelen As Integer) As Integer
Declare Function getservbyport Lib "Winsock.dll" (ByVal Port As Integer, ByVal proto As String) As Long
Declare Function getservbyname Lib "Winsock.dll" (ByVal serv_name As String, ByVal proto As String) As Long
Declare Function getprotobynumber Lib "Winsock.dll" (ByVal proto As Integer) As Long
Declare Function getprotobyname Lib "Winsock.dll" (ByVal proto_name As String) As Long
'WINDOWS EXTENSIONS
Declare Function WSAStartup Lib "Winsock.dll" (ByVal wVR As Integer, lpWSAD As WSADataType) As Integer
Declare Function WSACleanup Lib "Winsock.dll" () As Integer
Declare Sub WSASetLastError Lib "Winsock.dll" (ByVal iError As Integer)
Declare Function WSetLastError Lib "Winsock.dll" () As Integer
Declare Function WSAIsBlocking Lib "Winsock.dll" () As Integer
Declare Function WSAUnhookBlockingHook Lib "Winsock.dll" () As Integer
Declare Function WSASetBlockingHook Lib "Winsock.dll" (ByVal lpBlockFunc As Long) As Long
Declare Function WSACancelBlockingCall Lib "Winsock.dll" () As Integer
Declare Function WSAAsyncGetServByName Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal serv_name As String, ByVal proto As String, ByVal buf As String, ByVal buflen As Integer) As Integer
Declare Function WSAAsyncGetServByPort Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal Port As Integer, ByVal proto As String, ByVal buf As String, ByVal buflen As Integer) As Integer
Declare Function WSAAsyncGetProtoByName Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal proto_name As String, ByVal buf As String, ByVal buflen As Integer) As Integer
Declare Function WSAAsyncGetProtoByNumber Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal number As Integer, ByVal buf As String, ByVal buflen As Integer) As Integer
Declare Function WSAAsyncGetHostByName Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal host_name As String, ByVal buf As String, ByVal buflen As Integer) As Integer
Declare Function WSAAsyncGetHostByAddr Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal addr As String, ByVal addr_len As Integer, ByVal addr_type As Integer, ByVal buf As String, ByVal buflen As Integer) As Integer
Declare Function WSACancelAsyncRequest Lib "Winsock.dll" (ByVal hAsyncTaskHandle As Integer) As Integer
Declare Function WSAAsyncSelect Lib "Winsock.dll" (ByVal s As Integer, ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal lEvent As Long) As Integer
Declare Function WSARecvEx Lib "Winsock.dll" (ByVal s As Integer, buf As Any, ByVal buflen As Integer, ByVal flags As Integer) As Integer
#ElseIf Win32 Then
'SOCKET FUNCTIONS
C语言编写TCP的文件传输
为了设计统一和用户操作方便,我们希望将服务端与客户端融合在一起,形成一个程序,这样用户理解起来,更加直观一点(其实这样做也是为了方便调试,大家可以在本机上测试,自己传文件给自己)。所以,我们在程序中需要使用两个Winsock控件,一个负责监听,一个负责发送,当发送端连接成功以后,便选择一个待发送的文件(可以是任意二进制文件),接着将文件名和文件字节长度发送给接收端,接收端收到这个消息以后,将文件名和文件长度解析出来,然后通知发送端可以开始发送文件;发送端读到这个消息之后,将文件流以字节的形式发送到接收端,接收端收到后,将二进制流回写,保存成文件即可。这里要注意两点,一个是由于Winsock每次最大传输8K的内容,所以需要将文件分解,每次传输固定数目的字节流,这样发送和接收时都可以根据这个数目来判断文件传输的进程,一旦字节流数目等于文件的大小,就需要关闭相应的文件句柄;另一点是由于我只使用一个Winsock控件接收,接收文本时需要注意要将UNICODE转码,解析成可识别的信息。
源代码
'下面的代码既是服务器又是客户端
'用应答式发送方式
'自动拆分文件,包括2进制
Option Explicit
'Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Dim mybyte() As Byte '发送方数组
Const filecomesMSG = "a file is coming " '有文件到来
Const RemoteIsReadyMSG = "sender is ready " '准备好了
Const FileisOverMSG = "the file is ended" '文件完毕
Const RemoteDenyMSG = "the user canceled" '用户取消
Const filecountMSG = "the file lengh is" '文件长度
Const RecevieIsReadyMSG = "Receiver is ready " '准备接收
Dim arrdata() As Byte '收到的信息
Dim filese As Integer '保存文件的句柄
Dim filehandle As Integer '发送方文件的句柄
Dim FileSize As Double '文件的大小
Dim Sendbyte As Long
Dim Receivebyte As Long
Dim MyLocation As Double
Dim myMSG As String '消息
Dim FileisOver As Boolean '文件是否已经完毕
Const ReceivePort = 7905
Const BUFFER_SIZE = 5734
Private Sub cmdConnect_Click()
Timer2.Enabled = True
End Sub
Private Sub cmdsend_Click()
On Error GoTo errorhandle
With CommonDialog1
.CancelError = True
.DialogTitle = "选择您要传送的文件"
.Filter = "All Files (*.*)|*.*"
.ShowOpen
End With
filehandle = FreeFile
Open CommonDialog1.FileName For Binary Access Read As #filehandle
cmdSend.Enabled = False
FileSize = CDbl(FileLen(CommonDialog1.FileName))
Label1.Caption = "等待回应>>>"
MsgBox ("选择的文件大小为 " & LOF(filehandle) & " 字节")
If WinsockSend.State = sckConnected Then
WinsockSend.SendData filecomesMSG & CommonDialog1.FileName '发送发出文件信息
End If
Exit Sub
errorhandle:
cmdSend.Enabled = True
MsgBox ("你没有选择一个文件!")
End Sub
Private Sub Form_Load()
WinsockReceive.LocalPort = ReceivePort
WinsockReceive.Listen
FileisOver = True
Label1.Caption = "准备传输>>>"
End Sub
Public Function SendChunk()
Dim mybytesize As Long
If WinsockSend.State <> sckConnected Then Exit Function
mybytesize = BUFFER_SIZE
If LOF(filehandle) - Loc(filehandle) < BUFFER_SIZE Then mybytesize = (LOF(filehandle) - Loc(filehandle))
ReDim mybyte(0 To mybytesize - 1)
Get #filehandle, , mybyte
WinsockSend.SendData mybyte
Sendbyte = Sendbyte + mybytesize
ProgressBar1.Value = Int((100 / FileSize) * Sendbyte)
If Sendbyte >= FileSize Then
FileisOver = True
WinsockSend.SendData FileisOverMSG
End If
End Function
Private Sub Timer2_Timer()
If WinsockSend.State = sckConnected Then
Timer2.Enabled = False
cmdConnect.Enabled = False
ElseIf WinsockSend.State <> 1 And WinsockSend.State <> 6 And WinsockSend.State <> 7 And WinsockSend.State <> 8 And WinsockSend.State <> 9 Then
WinsockSend.Connect txtHost.Text, ReceivePort
ElseIf WinsockSend.State = 8 Or WinsockSend.State = 9 Then
WinsockSend.Close
End If
End Sub
Private Sub WinsockReceive_ConnectionRequest(ByVal requestID As Long)
If WinsockReceive.State <> sckClosed Then WinsockReceive.Close
WinsockReceive.Accept requestID
End Sub
Private Sub WinsockReceive_DataArrival(ByVal bytesTotal As Long)
ReDim arrdata(0 To bytesTotal - 1)
WinsockReceive.GetData arrdata, vbByte + vbArray
myMSG = StrConv(arrdata, vbUnicode) '二进制转为字符串
Select Case Mid(myMSG, 1, 17)
Case filecomesMSG '这些消息发送方和接受方都可收到
'显示保存对话框
On Error GoTo errorhandle
CommonDialog1.FileName = Mid(myMSG, 17, Len(myMSG))
CommonDialog1.DialogTitle = "选择保存文件的路径"
CommonDialog1.ShowSe
filese = FreeFile
Receivebyte = 0
cmdSend.Enabled = False
WinsockReceive.SendData RecevieIsReadyMSG
Case FileisOverMSG
Close #filese
MsgBox ("文件传输成功!") '大家一起处理
cmdConnect.Enabled = True
cmdSend.Enabled = True
Label1.Caption = "准备传输>>>"
ProgressBar1.Value = 0
WinsockReceive.SendData FileisOverMSG
WinsockReceive.Close
WinsockReceive.Listen
Case filecountMSG
FileSize = Mid(myMSG, 18, Len(myMSG))
Open CommonDialog1.FileName For Binary Access Write As #filese
WinsockReceive.SendData RemoteIsReadyMSG
Label1.Caption = "文件准备传输!"
FileisOver = False
Case Else
If Receivebyte < FileSize Then
Receivebyte = Receivebyte + bytesTotal
Put #filese, , arrdata
WinsockReceive.SendData RemoteIsReadyMSG
ProgressBar1.Value = Int((100 / FileSize) * Receivebyte)
End If
End Select
Exit Sub
errorhandle:
WinsockReceive.SendData RemoteDenyMSG
cmdConnect.Enabled = True
End Sub
Private Sub WinsockSend_DataArrival(ByVal bytesTotal As Long)
WinsockSend.GetData myMSG
Select Case myMSG
Case RecevieIsReadyMSG
WinsockSend.SendData filecountMSG & FileSize
FileisOver = False
Sendbyte = 0
Case RemoteIsReadyMSG
'如果文件还没有结束,继续传输
If Not FileisOver Then
Label1.Caption = "文件正在被传输>>>"
SendChunk
Else
WinsockSend.SendData FileisOverMSG
End If
Case FileisOverMSG
'主机处理
Close #filehandle
MsgBox ("文件传输成功!") '大家一起处理
WinsockSend.SendData FileisOverMSG
WinsockSend.Close
cmdConnect.Enabled = True
ProgressBar1.Value = 0
cmdSend.Enabled = True
Label1.Caption = "准备传输>>>"
Case RemoteDenyMSG
MsgBox ("用户终止了传输!")
cmdSend.Enabled = True
Label1.Caption = "准备传输>>>"
Close #filehandle
End Select
Exit Sub
winsock文件传输问题
粗略看了一下,你是用户的是TCP不是UDP,注意一点TCP可靠安全但是需要你自己手动处理粘包问题.你要是想学网络编程,就需要学会分析和定制协议.我建议你先去看看TFTP的网络协议.所谓的通信就是我发请求给你,你给我应答(请求成功还是失败).你刚学网络编程,直接是使用tcp不是很合适,你可以去看看TFTP的协议(向服务器请求下载或者上传文件).复杂一点的程序一搬都需要定制网络协议,tcp则还需要处理粘包问题.如果你想学,可以和我联系,我可以发你资料→_→
如何用VB实现数据文件传输? 最好有代码和窗口或者注明有哪些控件
建议你参考一下网上一些下载文件的程序..
winsock senddata "file:"+data()
这样肯定不行,要么你把前面的文件信息转成数组,要么就直接发送,服务器端都以数组方式接收,收到以后尝试转换为字符串,如果是文件头信息就处理,不是就写入文件
客户端这样来做
读取文件名,大小等数据先发送过去,然后再打开文件以数组形式发送
服务器端,接收到数据时先看看是否文件头,如果是文件头则处理,不是文件头就直接写入
有问题你可以继续补充
怎么用 Winsock 发送大于1M以上的数据
用winsock控件
以二进制方式打开文件
open file for binary
一次发送特定字节(编码:头几个或十几个字节用于控制、比如控制发送文件内容、文件名、发送序列等)
Winsock发送端要设置好协议(UPD或TCP)、远程IP、端口
接收端设置好协议和端口监听、
收到时解码(解出文件名、内容字节、写入字节位置等)并写出文件。
vb怎么实现远程文件传输
用分段发送的办法,具体代码如下:
发送端代码:
需要一个按钮,一个winsock控件一个commondialog控件
代码如下:
Option Explicit
Private Sub Command1_Click()
CommonDialog1.ShowOpen
If CommonDialog1.FileName = "" Then Exit Sub
If Winsock1.State = sckConnected Then
Command1.Enabled = False
Winsock1.SendData "FILE" & Chr(0) & CommonDialog1.FileName & Chr(0) & FileLen(CommonDialog1.FileName) & Chr(0)
End If
End Sub
Private Sub Form_Load()
Winsock1.Protocol = sckTCPProtocol
Winsock1.LocalPort = 7878
Winsock1.Listen
End Sub
Private Sub Winsock1_Close()
Print "链接断开"
Winsock1.Close
Winsock1.Listen
Command1.Enabled = True
End Sub
Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
Winsock1.Close
Winsock1.Accept requestID
Print "接受链接" & Winsock1.RemoteHostIP & ":" & Winsock1.RemotePort
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim s As String
If Winsock1.State = sckConnected Then
Winsock1.GetData s
Select Case s
Case "FILEOK"
Dim d(1 To 512) As Byte
Open CommonDialog1.FileName For Binary As #1
Get #1, , d
Winsock1.SendData d()
Case "DATAOK"
Print "传输完成"
Command1.Enabled = True
Close #1
Case "PACKETOK"
Get #1, , d
Winsock1.SendData d()
Case "CANCEL"
Command1.Enabled = True
Print "传输请求被拒绝"
End Select
End If
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
End Sub
接收端代码:需要一个winsock和一个commondialog
Option Explicit
Private Enum MyState
stClose = 0
stConnected = 1
stDataRequest = 2
End Enum
Private WskState As MyState
Private Sub Form_Load()
Me.Show
Winsock1.Connect "127.0.0.1", "7878"
WskState = stClose
End Sub
Private Sub Winsock1_Connect()
Print "链接成功"
WskState = stConnected
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim s As String
Dim r
Dim d() As Byte
Static Flen As Long
Static TransLen As Long
Dim fname As String
Select Case WskState
Case stConnected
Winsock1.GetData s
r = Split(s, Chr(0))
If r(0) = "FILE" And UBound(r) = 3 Then
Flen = Val(r(2))
fname = r(1)
While InStr(fname, "\") > 0
fname = Mid(fname, InStr(fname, "\") + 1)
Wend
CommonDialog1.FileName = fname
On Error GoTo Ers
CommonDialog1.CancelError = True
CommonDialog1.ShowSe
On Error GoTo 0
Open CommonDialog1.FileName For Output As #1
Close #1
Open CommonDialog1.FileName For Binary As #1
Winsock1.SendData "FILEOK"
WskState = stDataRequest
TransLen = 0
End If
Case stDataRequest
Winsock1.GetData d(), vbArray + vbByte, bytesTotal
TransLen = TransLen + bytesTotal
If TransLen >= Flen Then
Dim i As Long
For i = 0 To Flen Mod bytesTotal
Put #1, , d(i)
Next i
WskState = stConnected
Winsock1.SendData "DATAOK"
Close #1
Else
Put #1, , d
Winsock1.SendData "PACKETOK"
End If
Case Else
Winsock1.GetData s
Print "Unknown reuqest :" & s
End Select
Exit Sub
Ers:
Winsock1.SendData "CANCEL"
Print "拒绝传输"
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
Call Form_Load
End Sub
'不明白的百度HI我,我把工程发给你
vb6.0怎么用winsock发送大文件
用WINSOCK控件
Winsock控件对用户是不可视的,可以很容易地访问TCP和UDP网络服务。其可以被Microsoft Access, Visual Basic ,Visual C++或Visual FoxPro开发人员使用。要编写客户和服务器应用程序,不需要了解TCP或调用底层Winsock API的具体细节。通过设置Winsock控件的属性和调用该控件的方法,可以很容易地连接到远程计算机并进行双向的数据交换。
属性
BytesReceived属性,LocalHostName属性,LocalIP属性,LocalPort属性,RemoteHost属性(ActiveX控件),SocketHandle属性,State属性(Winsock控件),Protocol属性(Winsock控件),Name属性,Parent属性,RemoteHost属性(ActiveX控件),RemotePort属性(ActiveX控件),Index属性(ActiveX控件),Tag属性(ActiveX控件),Object属性(ActiveX控件)。
方法
Accept方法,Bind方法,Close方法(Winsock控件),Listen方法,PeerData方法,SendData方法,GetData方法(WinSock控件),GetData方法(ActiveX控件)。
Close,ConnectionRequest,DataArrival,SendComplete,SendProgress,Error,Connect(Winsock控件),Connect。
Winsock 控件对用户来说是不可见的,它提供了访问 TCP 和 UDP 网络服务的方便途径。Microsoft Access、Visual Basic、Visual C++ 或 Visual FoxPro 的开发人员都可使用它。为编写客户或服务器应用程序,不必了解 TCP 的细节或调用低级的 Winsock APIs。通过设置控件的属性并调用其方法就可轻易连接到一台远程机器上去,并且还可双向交换数据。
TCP 基础
数据传输协议允许创建和维护与远程计算机的连接。连接两台计算机就可彼此进行数据传输。
如果创建客户应用程序,就必须知道服务器计算机名或者 IP 地址(RemoteHost 属性),还要知道进行“侦听”的端口(RemotePort 属性),然后调用 Connect 方法。
如果创建服务器应用程序,就应设置一个收听端口(LocalPort 属性)并调用 Listen 方法。当客户计算机需要连接时就会发生 ConnectionRequest 。为了完成连接,可调用 ConnectionRequest 内的 Accept 方法。
建立连接后,任何一方计算机都可以收发数据。为了发送数据,可调用 SendData 方法。当接收数据时会发生 DataArrival 。调用 DataArrival 内的 GetData 方法就可获取数据。
UDP 基础
用户数据文报协议 (UDP) 是一个无连接协议。跟 TCP 的操作不同,计算机并不建立连接。另外 UDP 应用程序可以是客户机,也可以是服务器。
为了传输数据,首先要设置客户计算机的 LocalPort 属性。然后,服务器计算机只需将 RemoteHost 设置为客户计算机的 Internet 地址,并将 RemotePort 属性设置为跟客户计算机的 LocalPort 属性相同的端口,并调用 SendData 方法来着手发送信息。于是,客户计算机使用 DataArrival 内的 GetData 方法来获取已发送的信息。
VB如何实现传输语音和文件,我想做个聊天工具
这跟文件大小有什么关系。用内存映射技术读取大文件,用tcp协议的socket发送出去,多大的都没问题。要注意映射块的剩余量问题,不够一次发送量时要先暂存,读取下一映射块后再发送。这样实现可以达到局域网的最大带宽速度。如果偷懒使用win api,速度可能就几m而已。
传输语音和文件都可以通过Mswinsock 实现,只是速度方面我没有试过,我正巧最近也弄了点Mswinsock 相关的东西,代码发给你看看,希望有帮助
传送文件对于网络编程来说是基本的功能,比如远程控制软件。在编制一个软件时,我从网上下了很多传文件的程序,这些程序提供的传文件功能根本就不能用。传文本还可以,传二进制文件根本就不行。因此,作为一个基本的功能模块,有必要单独介绍一下。
首先,在VB中要传送字符串,你可以这样写:
Dim strData As String
strData = "Test"
Winsock1.SendData strData
但是如果你传送的二进制文件,你还能用String变量来存放吗?从理论上分析是不行的,我也做了实验,确实是不行的。文件虽然可以传,但是接受的文件和发送的不一样,原因可能是二进制文件里可以有任何"字符",但是不是所有的字符都可以放在String变量里。
除了String类型的变量,VB中其他类型的变量都只有几个字节长,难道一次只能发几个字节吗?那样岂不是要累死机器了!其实,情况没有那么悲观,我们完全可以使用数组来解决这个问题,就是使用byte数组。把要传送的文件都读到数组里,然后发送出去。程序如下:
FileName 为要传送的文件名,WinS为发送文件的WinSock控件。这是一个发送端的程序。
Public Sub SendFile(FileName As String, WinS As Winsock)
Dim FreeF As Integer ''空闲的文件号
Dim LenFile As Long ''文件的长度
Dim bytData() As Byte ''存放数据的数组
FreeF = FreeFile ''获得空闲的文件号
Open FileName For Binary As #FreeFile ''打开文件
DoEvents
LenFile = LOF(FreeFile) ''获得文件长度
ReDim bytData(1 To LenFile) ''根据文件长度重新定义数组大小
Get #FreeFile, , bytData ''把文件读入到数组里
Close #FreeFile ''关闭文件
WinS.SendData bytData ''发送数据
End Sub
接受端的程序如下:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim bytData() As Byte
Dim f
f = FreeFile
Open strFileName For Binary As #f
ReDim bytData(1 To bytesTotal)
Winsock1.GetData bytData
Put #f, i, bytData
i = i + bytesTotal ''保证每次写都是在文件的末尾, i是个全局变量
Close #f
End Sub
这里有两个需要注意的地方,ReDim Preserve bytData(1 To LenFile),下标是从1开始的,如果你写成ReDim bytData( LenFile),下标就是从0开始了,数组就有LenFile+1长了。LenFile = LOF(FreeFile)中的LOF是获得文件长度的函数,是VB里带的,我见过很多例子用API,或者循环的读直到末尾来获取文件长度,这样都是很麻烦的,使用LOF函数就可以了。
这样的程序,即可以传送文本文件,也可以传送二进制文件。但是你有没有发现这个程序的问题呢?如果我要传送一个50M的文件呢?系统可以为bytData分配50M的内存空间吗?
于是笔者拿一个50M的文件做实验吧,接收到的文件和原来的文件不一样,比原来的大。问题出在那呢?
首先,根据文件大小重新定义bytData数组的大小本身就有问题,系统是不可能无限制的给数组分配空间的,即使可以,也会造成系统响应变慢。在传50M文件的时候,系统就跟死机了一样。那么怎么解决这个问题呢,一个自然的想法就是把数据分段传送。程序如下:
发送程序, iPos是个全局变量,初始值为0。这个变量保存着当前数据的位置。Const iMax = 65535是每个数据块的大小。
Dim FreeF As Integer ''空闲的文件号
Dim LenFile As Long ''文件的长度
Dim bytData() As Byte ''存放数据的数组
FreeF = FreeFile ''获得空闲的文件号
Open FileName For Binary As #FreeF ''打开文件
DoEvents
LenFile = LOF(FreeF) ''获得文件长度
If LenFile <= iMax Then ''如果要发送的文件小于数据块大小,直接发送
ReDim bytData(1 To LenFile) ''根据文件长度重新定义数组大小
Get #FreeF, , bytData ''把文件读入到数组里
Close #FreeF ''关闭文件
WinS.SendData bytData ''发送数据
Exit Sub
End If
''文件大于数据块大小,进行分块发送
Do Until (iPos >= (LenFile - iMax)) ''发送整块数据的循环
ReDim bytData(1 To iMax)
Get #FreeF, iPos + 1, bytData
WinS.SendData bytData
iPos = iPos + iMax ''移动iPos,使它指向下来要读的数据
Loop
''这里要注意的是,必须检查文件有没有剩下的数据,如果文件大小正好等于数据块大小的
'' 整数倍,那么就没有剩下的数据了
ReDim bytData(1 To LenFile - iPos) ''发送剩下的不够一个数据块的数据
Get #FreeF, iPos + 1, bytData
WinS.SendData bytData
Close #FreeF
下面是接收端的程序:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim bytData() As Byte
Dim lLenFile As Long
Dim f
f = FreeFile
Open strFileName For Binary As #f ''strFileName是文件名
lLenFile = LOF(f)
ReDim bytData(1 To bytesTotal)
Winsock1.GetData bytData
If lLenFile = 0 Then ''lLenFile=0表示是第一次打开文件,这里有个问题,就是''如果如果该文件存在的话,就会出错,应该在打开前检查文件是否存在。(这里我省略了)
Put #f, 1, bytData
Else
Put #f, lLenFile + 1, bytData
End If
Close #f
End Sub
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。