vb winsock客户端关闭后二次连接问题

vb winsock客户端关闭后二次连接问题,第1张

winsork 发起连接时到结束前 不能再次发起连接!

就像你面前有个水杯 你要倒牛奶 又要倒水喝 ,所以你必须先喝完牛奶再倒水!

如果是多用户登陆:

winsork需要建立 控件组~

每个用户winsork1对应一个服务端的winsork1(n).

组成1对1的 连接关系!

网络编程——聊天室(代码如下)

本程序是基于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("")


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/280513.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-21
下一篇2023-04-21

发表评论

登录后才能评论

评论列表(0条)

    保存