vb6的服务器后端(Frm):
思路是通过for循环检测socket是否空闲,若为空闲则打开监听模式,若所有socket都处于忙碌状态则动态添加新的socket控件,当收到新的消息时,由byte数组转换为unchoice,并进行字符串处理写入服务器的“群聊.txt"中,使用for循环,让已经链接客户端的socket发送txt的内容,
gettext()都是封装在dll的函数可以到底部的gitee项目地址查看
VERSION 5.00
Object = "{248DD890-BB45-11CF-9ABC-0080C7E7B78D}#1.0#0"; "MSWINSCK.OCX"
Object = "{3B7C8863-D78F-101B-B9B5-04021C009402}#1.2#0"; "richtx32.ocx"
Begin VB.Form Form1
Caption = "基于tcp的即时通讯"
ClientHeight = 6105
ClientLeft = 60
ClientTop = 405
ClientWidth = 7950
LinkTopic = "Form1"
ScaleHeight = 6105
ScaleWidth = 7950
StartUpPosition = 3 '窗口缺省
Begin VB.CommandButton Command1
Caption = "生成日志包"
Height = 615
Left = 2760
TabIndex = 1
Top = 5400
Width = 2055
End
Begin VB.Timer Timer2
Interval = 100
Left = 6240
Top = 720
End
Begin VB.Timer Timer1
Interval = 100
Left = 6720
Top = 2280
End
Begin RichTextLib.RichTextBox text1
Height = 4335
Left = 600
TabIndex = 0
Top = 720
Width = 5775
_ExtentX = 10186
_ExtentY = 7646
_Version = 393217
Enabled = -1 'True
TextRTF = $"Form1.frx":0000
End
Begin MSWinsockLib.Winsock Winsock1
Index = 0
Left = 7200
Top = 3360
_ExtentX = 741
_ExtentY = 741
_Version = 393216
LocalPort = 10000
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Dim sockets As Long, socketpeo As Long
Private Sub cl(data1 As String, socknum As Integer)
GETI = Split(data1, "-")
id = Mid(GETI(1), 6)
gid = Mid(GETI(2), 7)
txt = Mid(GETI(3), 6)
Call SetText(App.Path + "\DATA\record\" & gid & ".txt", 3, id & ":" & txt)
End Sub
Private Sub Command1_Click()
Call SetText(App.Path + "\LOG.log", 1, text1.Text)
End Sub
Private Sub text1_Change()
text1.SelStart = Len(text1.Text) - 1
End Sub
Private Sub Timer1_Timer()
If socketpeo > sockets Then
sockets = sockets + 1
Load Winsock1(sockets)
End If
For i = 0 To sockets
If Winsock1(sockets).State <> 7 Then
Winsock1(sockets).Close
Winsock1(sockets).Listen
End If
Next
End Sub
Private Sub Winsock1_Close(Index As Integer)
socketpeo = socketpeo - 1
End Sub
Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)
If Winsock1(Index).State <> sckClosed Then
Winsock1(Index).Close
Winsock1(Index).Accept requestID
For i = 0 To sockets
text1.Text = text1.Text & vbCrLf & CStr(Date) & CStr(Time) & ":接受请求时的state winscok1(" & Index & ") state=" & Winsock1(Index).State
Next
text1.Text = text1.Text & vbCrLf & CStr(Date) & CStr(Time) & ": 当前socket服务端数量" & sockets & "客户机数量" & socketpeo
text1.Text = text1.Text & vbCrLf & CStr(Date) & CStr(Time) & ":" & requestID & "与服务端进行了连接 socket号:" & Index
socketpeo = socketpeo + 1
End If
End Sub
Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim data1(50000000) As String
Dim bb() As Byte
Winsock1(Index).GetData bb()
data1(Index) = StrConv(bb(), vbUnicode)
If Left(data1(Index), 5) = "bind:" Then
Winsock1(Index).Tag = Mid(data1(Index), 6)
text1.Text = text1.Text & vbCrLf & CStr(Date) & CStr(Time) & ":接到命令绑定id:" & Winsock1(Index).Tag
Else
Call cl(data1(Index), Index)
End If
text1.Text = text1.Text & vbCrLf & CStr(Date) & CStr(Time) & ": 当前socket服务端数量" & sockets & "客户机数量" & socketpeo
text1.Text = text1.Text & vbCrLf & CStr(Date) & CStr(Time) & ": 当前接收到一个客户端socket传来的数据" & data1(1) & "服务器socket号" & Index & "接收的数据:" & data1(Index)
For i = 0 To sockets
If Winsock1(i).State = 7 And Dir(App.Path + "\data\record\" & Winsock1(i).Tag & ".txt") <> "" Then
text1.Text = text1.Text & vbCrLf & CStr(Date) & CStr(Time) & "winsocket(" & i & ") 发送了数据包"
Winsock1(i).SendData (GetText(App.Path + "\data\record\" & Winsock1(i).Tag & ".txt"))
DoEvents
End If
Next
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)
text1.Text = text1.Text & vbCrLf & CStr(Date) & CStr(Time) & ": 当前" & Index & "号socket服务出现故障"
Call SetText(App.Path + "\Error.txt", 3, CStr(Date) & CStr(Time) & ":socket号:" & Index & "错误号" & Number & "描述" & Description)
End Sub
Client端(Frm):
login.frm:
这个文件只是简易的登录界面,并确认用户名和群聊号
VERSION 5.00
Begin VB.Form login
BorderStyle = 1 'Fixed Single
Caption = "login"
ClientHeight = 3135
ClientLeft = 45
ClientTop = 390
ClientWidth = 4680
LinkTopic = "Form2"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 3135
ScaleWidth = 4680
StartUpPosition = 3 '窗口缺省
Begin VB.Frame Frame1
Caption = "请输入"
Height = 2535
Left = 240
TabIndex = 0
Top = 360
Width = 4335
Begin VB.CommandButton Command2
Caption = "退出"
Height = 375
Left = 2640
TabIndex = 6
Top = 2040
Width = 1095
End
Begin VB.CommandButton Command1
Caption = "登录"
Height = 375
Left = 360
TabIndex = 5
Top = 2040
Width = 1095
End
Begin VB.TextBox Text2
Height = 495
Left = 960
TabIndex = 4
Top = 1200
Width = 3135
End
Begin VB.TextBox Text1
Height = 495
Left = 960
TabIndex = 1
Top = 360
Width = 3135
End
Begin VB.Label Label2
Caption = "聊天室号"
Height = 375
Left = 120
TabIndex = 3
Top = 1320
Width = 735
End
Begin VB.Label Label1
Caption = "用户名"
Height = 375
Left = 120
TabIndex = 2
Top = 480
Width = 615
End
End
End
Attribute VB_Name = "login"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Sub Command1_Click()
If TEXT1.Text <> "" And Text2.Text <> "" Then
gid = Text2.Text
username = TEXT1.Text
Me.Hide
chatroom.Show
Else
MsgBox "输入的不能为空", vbInformation, "提示"
End If
End Sub
Private Sub Command2_Click()
End
End Sub
chatroom.frm:
聊天室窗体
这个没啥好说的,发送的数据端格式基本为:-user:用户名-group:群号-text:内容
若发送的数据为bind:群号id 则是让服务器链接客户端的socket的tag为群号的id
接受数据与服务器相似
VERSION 5.00
Object = "{248DD890-BB45-11CF-9ABC-0080C7E7B78D}#1.0#0"; "MSWINSCK.OCX"
Object = "{3B7C8863-D78F-101B-B9B5-04021C009402}#1.2#0"; "richtx32.ocx"
Begin VB.Form chatroom
BorderStyle = 1 'Fixed Single
Caption = "基于tcp的即时通讯"
ClientHeight = 6450
ClientLeft = 45
ClientTop = 390
ClientWidth = 7950
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 6450
ScaleWidth = 7950
StartUpPosition = 3 '窗口缺省
Begin VB.Frame Frame1
Caption = "发送数据"
Height = 1935
Left = 120
TabIndex = 1
Top = 4440
Width = 7695
Begin RichTextLib.RichTextBox TEXT1
Height = 1215
Left = 240
TabIndex = 3
Top = 480
Width = 5895
_ExtentX = 10398
_ExtentY = 2143
_Version = 393217
Appearance = 0
TextRTF = $"chatroom.frx":0000
End
Begin VB.CommandButton Command1
Caption = "发送"
Height = 735
Left = 6240
TabIndex = 2
Top = 720
Width = 1335
End
End
Begin VB.Timer Timer1
Interval = 100
Left = 4080
Top = 2400
End
Begin MSWinsockLib.Winsock Winsock1
Left = 120
Top = 120
_ExtentX = 741
_ExtentY = 741
_Version = 393216
RemoteHost = "192.168.0.40"
RemotePort = 10000
End
Begin RichTextLib.RichTextBox text3
Height = 3975
Left = 120
TabIndex = 0
Top = 360
Width = 7695
_ExtentX = 13573
_ExtentY = 7011
_Version = 393217
TextRTF = $"chatroom.frx":009D
End
End
Attribute VB_Name = "chatroom"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Sub Command1_Click()
If Winsock1.State = 7 Then
Winsock1.SendData "-user:" & username & "-group:" & gid & "-text:" & TEXT1.Text
TEXT1.Text = ""
DoEvents
Else
choice = MsgBox("连接服务器失败,是否重新连接", vbYesNo, "提示")
If choice = vbYes Then Call Form_Load Else End
End If
End Sub
Private Sub Form_Load()
text3.Locked = True
Winsock1.Close
Winsock1.Connect
End Sub
Private Sub text2_Change()
End Sub
Private Sub Form_Unload(Cancel As Integer)
End
End Sub
Private Sub Winsock1_Connect()
a = startT
Do While get_time(a) < 7
DoEvents
If Winsock1.State = 7 Then
Winsock1.SendData "bind:" & gid
Exit Do
End If
Loop
If Winsock1.State <> 7 Then
choice = MsgBox("连接服务器失败,是否重连", vbYesNo, "提示")
If choice = vbYes Then Call Form_Load Else End
End If
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim bb() As Byte
Winsock1.GetData bb()
Data1 = StrConv(bb(), vbUnicode)
text3.Text = Data1
End Sub
dll库的源码和使用方法可到gitee项目地址查看