本程序是基於VB開發環境中Winsock控件的應用,遵循TCP/IP協議,利用該控件的套接字功能,實現遠程計算機之間數據通信的,它由服務器和客戶端組成。服務器用於連接多個客戶端,可以統計已經連接過服務器的人數和服務器當前的在線人數,並負責收發各客戶發送的消息,實現多個客戶之間實時、準確、無誤的數據通信。該程序可以連接1000個客戶端,而如果要增減可供連接的客戶端,只需對源程序的客戶上限稍加改動即可。
工作原理
服務器:運行時聲明壹組Winsock控件數組,只創建該數組的第壹個數組元素並從9999端口開始偵聽(listen),當有客戶端連接第壹個Winsock控件並且連接成功時,觸發Winsock_ConnectRequest()事件,端口數(Localport)遞減1單位,此時運用Load Winsock(i)方法創建下壹個Winsock控件數組元素並讓它開始偵聽,繼續等待新客戶端的連接,如此往復。當連接人數達到既定的客戶端上限時,服務器便停止創建新的Winsock控件數組元素,停止偵聽,即停止連接客戶。服務器與客戶端連接成功之後,通過Winsock的DataArrival()事件、SendData和GetData方法來實現數據的發送和接收。服務器中用壹個Locked屬性設定為True的文本框來記錄所有客戶發送的消息(聊天記錄)。
客戶端:運行時只創建壹個Winsock控件,從9999開始遞減依次指定Winsock的遠程端口並依次連接遠程服務器,壹旦連接成功就停止指定端口,且由此可以開始和服務器通信。
用壹個Locked屬性設定為True的文本框來記錄所有客戶發送的消息,用壹個可編輯的文本框來輸入客戶要發送的消息,這樣就基本實現了聊天室的功能。
程序代碼
服務器:
Option Explicit
Dim guest As Integer '在線客戶數量計數器
Dim j As Integer '已接客戶數量計數器
Dim k As Integer '向在線客戶發送消息數量計數器
Dim t As Integer '關閉服務器時向在線客戶發送消息數量計數器
Dim port As Integer '端口計數器
Dim msg As String '收發的消息文本
Dim newguest As Integer '新客戶連接
Private Sub Form_Load()
If App.PrevInstance Then MsgBox "對不起!您已經創建了壹個服務器^_^": End
j = 0
guest = 0
port = 9999
Text2 = Winsock1(0).LocalIP
Label3.Caption = "在線人數:" & guest
Label4.Caption = "已接人數:" & j
Winsock1(0).LocalPort = port 'Winsock控件數組第壹個控件開始偵聽
Winsock1(0).Listen
End Sub
Private Sub Form_Unload(Cancel As Integer) '關閉服務器時緩沖,發送斷開信號
Cancel = 1
t = 0
Timer2.Enabled = 1
End Sub
Private Sub Timer1_Timer()
On Error Resume Next '錯誤處理
Winsock1(k).SendData msg '向所有客戶發送即時收到的消息
k = k + 1
If k >= j Then Timer1.Enabled = 0
End Sub
Private Sub Timer2_Timer() '向客戶發送斷開信號
On Error Resume Next
msg = "closewinsock"
Winsock1(t).SendData msg
t = t + 1
If t > j Then End
End Sub
Private Sub Timer3_Timer() '向新客戶發送歡迎信息
On Error Resume Next
If k = newguest Then Exit Sub
Winsock1(k).SendData msg
k = k + 1
If k >= j Then Timer3.Enabled = 0
End Sub
Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)
On Error Resume Next
Dim onlineperson As String
msg = ""
If Winsock1(Index).State <> sckClosed Then Winsock1(Index).Close '成功連接
Winsock1(Index).Accept requestID
j = j + 1 '統計已接人數
If guest + 1 < 10 Then
onlineperson = "currentonlineperson00" + CStr(guest + 1) + msg
ElseIf guest + 1 < 100 Then
onlineperson = "currentonlineperson0" + CStr(guest + 1) + msg
End If
Winsock1(Index).SendData onlineperson & "您是第" & CStr(j) & "位進入本聊天室的客戶^_^" + Chr(13) + Chr(10)
msg = onlineperson & "第" & CStr(j) & "位客戶進入了本聊天室" + Chr(13) + Chr(10)
Text1 = Text1 +"第" & CStr(j) & "位客戶進入了本聊天室" + Chr(13) + Chr(10)
k = 0
newguest = Index
Timer3.Enabled = 1
Text1.SelStart = Len(Text1)
guest = guest + 1 '統計在線人數
Label3.Caption = "在線人數:" & guest
Label4.Caption = "已接人數:" & j
Load Winsock1(j)
port = port - 1
Winsock1(j).LocalPort = port
Winsock1(j).Listen
End Sub
Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)
On Error Resume Next
Dim i As Integer
Dim onlineperson As String
msg = ""
Winsock1(Index).GetData msg '發送斷開信號
If msg = "closewinsock" Then
msg = ""
Winsock1(Index).Close
If guest - 1 < 10 Then
onlineperson = "currentonlineperson00" + CStr(guest - 1)
ElseIf guest < 100 Then
onlineperson = "currentonlineperson0" + CStr(guest - 1)
End If
msg = "第" & CStr(Index + 1) & "位客戶已經離開" + Chr(13) + Chr(10)
Text1 = Text1 + msg
msg = onlineperson & "第" & CStr(Index + 1) & "位客戶已經離開" + Chr(13) + Chr(10)
Text1.SelStart = Len(Text1)
k = 0
Timer1.Enabled = 1
guest = guest - 1
Label3.Caption = "在線人數:" & guest
Label4.Caption = "已接人數:" & j
Exit Sub
End If
msg = "第" + CStr(Index + 1) + "位客戶說:" + msg + Chr(13) + Chr(10)
Text1 = Text1 + msg
Text1.SelStart = Len(Text1)
k = 0
Timer1.Enabled = 1
End Sub
客戶端:
Dim linkstate As Boolean '判斷連接狀態
Dim port As Integer '依次嘗試連接的端口
Private Sub Cmdconnect_Click()
On Error Resume Next
Dim t As String
Dim x As String
Dim y As Integer
y = 0
If Len(Text1) = 0 Then Exit Sub '判斷輸入的IP地址是否合法
For i = 1 To Len(Text1)
If Mid(Text1, i, 1) <> "." Then
t = t + Mid(Text1, i, 1)
x = ""
Else
y = y + 1
x = x + Mid(Text1, i, 1)
t = ""
End If
If Len(t) > 3 Or x = ".." Or Left(Text1, 1) = "." Or Right(Text1, 1) = "." Then
MsgBox "請輸入正確的IP地址^_^", vbOKOnly + vbInformation, "連接": Exit Sub
End If
Next i
If y <> 3 Then MsgBox "請輸入正確的IP地址^_^", vbOKOnly + vbInformation, "連接": Exit Sub
If Text1 Like "*.*.*.*" Then
If Cmdconnect.Caption = "&Link" Then '用戶選擇連接
Cmdconnect.Caption = "&Break"
Timer1.Enabled = 1
Text1.Enabled = 0
Else '用戶選擇中斷連接
Label4.Caption = "在線人數:0"
Text2 = Text2 + "連接中斷" + Chr(13) + Chr(10)
Text2.SelStart = Len(Text2)
Timer1.Enabled = 0
Text1.Enabled = 1
Text1.SetFocus
Cmdconnect.Caption = "&Link"
Winsock1.SendData "closewinsock"
linkstate = False
port = 9999
Text3.Enabled = False
cmdsend.Enabled = False
End If
End If
End Sub
Private Sub cmdsend_Click()
On Error Resume Next '發送消息
Winsock1.SendData Text3
Text3 = ""
Text3.SetFocus
End Sub
Private Sub Form_Load()
linkstate = False
port = 9999
End Sub
Private Sub Form_Unload(Cancel As Integer)
On Error Resume Next
Winsock1.SendData "closewinsock" '向服務器發送斷開信號
Cancel = 1
Timer2.Enabled = 1
End Sub
Private Sub Text1_KeyPress(KeyAscii As Integer) '禁止用戶輸入非法IP地址
If KeyAscii < 48 Or KeyAscii > 57 Then
If KeyAscii <> 8 And KeyAscii <> 46 Then KeyAscii = 0
End If
End Sub
Private Sub Text2_KeyPress(KeyAscii As Integer)
If Text3.Enabled = False Then Exit Sub
If KeyAscii = 13 Then Call cmdsend_Click
Text3 = Text3 + Chr(KeyAscii)
End Sub
Private Sub Text3_KeyPress(KeyAscii As Integer)
If KeyAscii = 13 Then Call cmdsend_Click
End Sub
Private Sub Timer1_Timer() '從9999端口依次嘗試連接服務器
If linkstate = True Then Exit Sub
Winsock1.Close
Winsock1.RemoteHost = Text1.Text
Winsock1.RemotePort = port
Winsock1.Connect
port = port - 1
If port < 9000 Then '設置可供連接的端口上限
Timer1.Enabled = 0
Text1.Enabled = 1
Cmdconnect.Caption = "&Link"
port = 9999
MsgBox "無法連接到服務器,請檢查網絡連接狀況", vbOKOnly + vbCritical, "連接"
End If
End Sub
Private Sub Timer2_Timer() '緩沖以發送斷開信號
End
End Sub
Private Sub Winsock1_Connect()
port = port + 1
Timer1.Enabled = 0
linkstate = True
Text3.Enabled = 0
cmdsend.Enabled = 0
MsgBox "已經成功連接", vbOKOnly + vbInformation, "連接"
Text3.Enabled = 1
cmdsend.Enabled = 1
Text3.SetFocus
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim msg As String
Winsock1.GetData msg '接收服務器傳來的的數據並進行相應處理
If Left(CStr(msg), 19) = "currentonlineperson" Then
Label4.Caption = "在線人數:" & Str(Val(Mid(CStr(msg), 20, 3)))
msg = Right(CStr(msg), Len(CStr(msg)) - 22)
End If
If CStr(msg) = "closewinsock" Then
Call Cmdconnect_Click
Text2.SelStart = Len(Text2)
Exit Sub
End If
Text2 = Text2 + msg
Text2.SelStart = Len(Text2)
End Sub
回答者:海必揚波 - 童生 壹級 12-28 13:12
評價已經被關閉 目前有 1 個人評價
好
100% (1) 不好
0% (0)
其他回答*** 3 條
asp
回答者:dageda - 秀才 二級 12-22 02:54
public void actionPerformed(ActionEvent e)
{
int count,temp;
temp=ch.getSelectedIndex();
if(e.getSource()==btn1)
{
ch.select(--temp);
count=temp;
content.setText(String.valueOf(add1[temp]+ope2[temp]+add2[temp])+"=");
radio1.setLabel(String.valueOf(answer[temp][0]));
radio2.setLabel(String.valueOf(answer[temp][1]));
radio3.setLabel(String.valueOf(answer[temp][2]));
radio4.setLabel(String.valueOf(answer[temp][3]));
if(count==0)
{
btn1.setEnabled(false);
}
btn2.setEnabled(true);
txt1.setText("");
check1.setState(false);
correctLab.setVisible(false);
}
if(e.getSource()==btn2)
{
ch.select(++temp);
count=temp;
content.setText(String.valueOf(add1[temp]+ope2[temp]+add2[temp])+"=");
radio1.setLabel(String.valueOf(answer[temp][0]));
radio2.setLabel(String.valueOf(answer[temp][1]));
radio3.setLabel(String.valueOf(answer[temp][2]));
radio4.setLabel(String.valueOf(answer[temp][3]));
if(count==9)
{
btn2.setEnabled(false);
}
btn1.setEnabled(true);
txt1.setText("");
check1.setState(false);
correctLab.setVisible(false);
}
count=temp;
if(e.getSource()==txt1)
{
String name=txt1.getText();
if(name.equals(radio1.getLabel()))
{
radio1.setState(true);
}
if(name.equals(radio2.getLabel()))
{
radio2.setState(true);
}
if(name.equals(radio3.getLabel()))
{
radio3.setState(true);
}
if(name.equals(radio4.getLabel()))
{
radio4.setState(true);
}
}
}
public void itemStateChanged(ItemEvent e)
{
int count,temp;
if(e.getItemSelectable()==ch)
{
temp=ch.getSelectedIndex();
count=temp;
content.setText(String.valueOf(add1[temp]+ope2[temp]+add2[temp])+"=");
radio1.setLabel(String.valueOf(answer[temp][0]));
radio2.setLabel(String.valueOf(answer[temp][1]));
radio3.setLabel(String.valueOf(answer[temp][2]));
radio4.setLabel(String.valueOf(answer[temp][3]));
if(count==0)
{
btn1.setEnabled(false);
}
btn2.setEnabled(true);
if(count==9)
{
btn2.setEnabled(false);
}
btn1.setEnabled(true);
txt1.setText("");
check1.setState(false);
correctLab.setVisible(false);
}
if(e.getItemSelectable()==radio1)
{
txt1.setText(radio1.getLabel());
}
if(e.getItemSelectable()==radio2)
{
txt1.setText(radio2.getLabel());
}
if(e.getItemSelectable()==radio3)
{
txt1.setText(radio3.getLabel());
}
if(e.getItemSelectable()==radio4)
{
txt1.setText(radio4.getLabel());
}
if(e.getItemSelectable()==check1)
{
if(e.getStateChange()==e.SELECTED)
{
correctLab.setVisible(true);
temp=ch.getSelectedIndex();
correctLab.setText("正確答案是:"+String.valueOf(correct[temp]));
}
else if(e.getStateChange()==e.DESELECTED)
{
correctLab.setVisible(false);
}
}
}
}
public class xhks120
{
public static void main(String args[])
{
Myframe fr=new Myframe("");