100分求助,不够可以另开帖加分!循环中使用Winsock发送消息的问题。

free1688 2009-03-09 06:32:26
局域网内有多台电脑,大约200台,一台作服务器,其余客户端,实现功能是,在服务器端上面定时发送给符合条件的客户端发消息。发送消息的代码我在点击事件里面
Winsock1.Close
Winsock1.RemoteHost = Grd数据.TextMatrix(Grd数据.RowSel, 1)
Winsock1.RemotePort = "8888"
Winsock1.SendData "OFF"
Winsock1.Connect

这可以实现,但是,同样的代码加到timer里面,想通过循环给多个不同的客户端发消息,就出现了“40006”这样的通信问题,下面是我在服务器端的代码,我想我的代码有问题,但是我不会改下面的代码了,我对Winsock不很熟悉,希望高手指教!
Private Sub Timer1_Timer()
Set AboRS = AdoRecordset("SELECT * FROM 客户端表", "FIDSDATE.mdb")
With AboRS
.MoveFirst
Do Until .EOF

If .Fields("状态") = "OFF" And .Fields("IP地址") <> "" Then
Winsock1.Close
' Winsock1.Listen
Winsock1.RemoteHost = .Fields("IP地址")
Winsock1.RemotePort = "8888"
'Winsock1.Connect

Do While Winsock1.State = sckConnecting
DoEvents
Loop

Winsock1.SendData "OFF"
.MoveNext
ElseIf .Fields("状态") = "ON" And .Fields("IP地址") <> "" Then
Winsock1.Close
Winsock1.Listen
Winsock1.RemoteHost = .Fields("IP地址")

Winsock1.RemotePort = "8888"
Switch = False
Winsock1.Connect

Do While Winsock1.State = sckConnecting
DoEvents
Loop
'If Winsock1.State <> sckConnected Then Exit Sub '此时SockCL.State = 6
'If Winsock1.State <> 0 Then Winsock1.State = 0
'If Winsock1.State <> 0 Then: Winsock1.Close
Winsock1.SendData "ON"

.MoveNext
Else
.MoveNext
End If
Loop
End With
End Sub
...全文
233 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
free1688 2009-06-03
  • 打赏
  • 举报
回复
谢谢大家的解答,问题已经解决了。admincj的帮助下取得了一个新的控件,可以发送消息。改了一下我的代码,其实就是2行代码,加到合适的位置上就可以解决问题。现在散分。
ruihongli 2009-05-15
  • 打赏
  • 举报
回复
使用UDP行不?
admincj 2009-05-15
  • 打赏
  • 举报
回复
SocketMaster.ocx你用这个控件去试试吧。
admincj 2009-05-08
  • 打赏
  • 举报
回复
帮你顶一下,你可以换换思路,用另外的新的控件来实现。我见过一个新的控件,可以实现你的功能,你上网找找。
free1688 2009-04-17
  • 打赏
  • 举报
回复
客户端代码可能有问题,现在的问题是只有一个客户端,需要与多个服务器端定时通信通信,怎么实现呢?
free1688 2009-04-17
  • 打赏
  • 举报
回复
这是服务器端代码:
Option Explicit
Public LastState As Integer
Private Exitflag As Boolean
'Dim intMax As Long

Private Sub ExitCmd_Click()
Dim isok
isok = MsgBox("退出后将不能接收服务器消息, 是否要退出程序? ", vbYesNo, "是否退出程序")
If isok = vbYes Then
Exitflag = True
Unload Me
End If
End Sub

Private Sub Form_Load()
Dim 现在时间 As Date
Me.Visible = False '隐藏窗体
PortNumber.Text = 8888 '设置默认端口号
Winsock1.LocalPort = PortNumber.Text '设置默认端口号
Winsock1.Listen '监听端口
If WindowState = vbMinimized Then
LastState = vbNormal
Else
LastState = WindowState
End If


AddToStock Me, sysmenu '添加托盘
SetStockTip "点击可以打开窗体设置连接端口" '添加托盘提示
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If Exitflag Then
RemoveFromStock
Else
Me.Visible = False
Cancel = True
End If
End Sub


Private Sub menuExit_Click()
Call ExitCmd_Click
End Sub


Private Sub setPortCmd_Click()
Winsock1.Close
Winsock1.LocalPort = PortNumber.Text '设置默认端口号
Winsock1.Listen '监听端口
End Sub

Private Sub Winsock1_Close()
Winsock1.Close
End Sub

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
Winsock2.Accept requestID '响应Socket连接
End Sub



Private Sub Winsock2_Close()
Winsock2.Close
End Sub

Private Sub Winsock2_DataArrival(ByVal bytesTotal As Long)
Dim redata As String
Winsock2.GetData redata, vbString '取得指令
SetMonitor redata '根据指令设置
Winsock2.Close '关闭Socket连接
End Sub

Public Sub SetMonitor(data As String)
If data = "ON" Then '判断指令
MonitorOn Me
ElseIf data = "OFF" Then '判断指令
MonitorOff Me End If
End Sub
free1688 2009-04-17
  • 打赏
  • 举报
回复
大家有一个实例吗?一个客户端对应多个服务器端的代码实例?
surge0321 2009-03-30
  • 打赏
  • 举报
回复
学习
wpy110521 2009-03-30
  • 打赏
  • 举报
回复
飘过.
三楼の郎 2009-03-20
  • 打赏
  • 举报
回复
你只用了一个Winsock2来响应客户机的连接请求,所以你的代码最多只能有一台客户机进行连接,不能实现多客户机连接。
[Quote=引用 14 楼 free1688 的回复:]Private Sub Winsock2_DataArrival(ByVal bytesTotal As Long)
Dim redata As String
Winsock2.GetData redata, vbString '取得指令
SetMonitor redata '根据指令设置显示器
Winsock2.Close '关闭Socket连接
End Sub[/Quote]
你上面那段代码在Winsock2收到客户机的数据后就执行了Winsock2.Close,Close以后客户机与服务器的连接中断,服务器就不能再将任何消息发送至客户机,也不能从客户机接收任何消息。

你还是仔细看看5、6、7、10、12楼的回复吧!
admincj 2009-03-19
  • 打赏
  • 举报
回复
在你的服务器端需要用控件组来实现。建立动态控件组试试
Tiger_Zhao 2009-03-11
  • 打赏
  • 举报
回复
发起 Connect 的是客户端,进行 Listen 的(响应 ConnectionRequest 事件)的是服务端。
连接成功后,建立的通道是双向的,除了客户端(发起 Connect)的 WinSocket 控件可以 SendData,服务端要反馈信息可以直接用(执行了 Accept 的)WinSocket 控件进行 SendData,不需要反向进行 Connect 请求。
单独一个 WinSocket 不要同时做 Connect 和 Listen,如果程序要同时实现客户端和服务端,就用多个 WinSocket 实现。
free1688 2009-03-11
  • 打赏
  • 举报
回复
我可能没有说明白,“我所说的客户端”实际按照Winsock服务器端写的代码,负责接收“我所说的服务器”发的消息,不停接收消息,收到消息后处理按照消息内容执行相关处理。
“我所说的服务器”实际按照Winsock客户端写的代码,只是在循环里面按照数据库中的内容给各个 Winsock服务器端 发消息,这样写主要是为了稳定。现在的问题是Winsock客户端发送消息的部分在'Winsock1.Connect 之后,执行Winsock1.SendData "OFF" 时,出现了问题。我不知道这样的问题怎么处理,我的Winsock客户端的代码怎么处理?

Tiger_Zhao 2009-03-11
  • 打赏
  • 举报
回复
客户端发起 Connect 请求,服务端就有 ConnectionRequest 事件,你必须用一个空闲的 Winsock 控件进行 Accept,才能开始一对一通讯。
Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)
Dim i As Long

i = Winsock1.UBound + 1
Load Winsock1(i)
Winsock1(i).Accept requestID
Debug.Print "Accept(" & requestID & ") : " & Winsock1(i).RemoteHostIP
End Sub
free1688 2009-03-11
  • 打赏
  • 举报
回复
Winsock服务器端的代码是这么写的

Private Sub setPortCmd_Click()
Winsock1.Close
Winsock1.LocalPort = PortNumber.Text '设置默认端口号
Winsock1.Listen '监听端口
End Sub

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
Winsock2.Accept requestID '响应Socket连接
End Sub

Private Sub Winsock2_DataArrival(ByVal bytesTotal As Long)
Dim redata As String
Winsock2.GetData redata, vbString '取得指令
SetMonitor redata '根据指令设置显示器
Winsock2.Close '关闭Socket连接
End Sub
tongnaifu 2009-03-10
  • 打赏
  • 举报
回复
客户端大体代码如下:

Option Explicit
Dim blnCon As Boolean

Private Sub Form_Load()
Winsock1.Protocol = sckTCPProtocol
Winsock1.RemoteHost = "*.*.*.*"
Winsock1.RemotePort = 1010
End Sub

Private Sub Timer1_Timer()
If blnCon = False Then
If Winsock1.State = 0 Then
Winsock1.Connect
ElseIf Winsock1.State = 7 Then
'发送处理代码
blnCon = True
Else
Winsock1.Close
End If
End If
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
'事件处理代码
End Sub

tongnaifu 2009-03-10
  • 打赏
  • 举报
回复
服务器端:

Option Explicit
Dim intMax As Long
Private Sub Form_Load()
intMax = 0
Winsock1(0).Protocol = sckTCPProtocol
Winsock1(0).LocalPort = 8888
Winsock1(0).Listen
End Sub

Private Sub Winsock1_ConnectionRequest(index As Integer, ByVal requestID As Long)
Dim i As Long
For i = 1 To intMax
If Winsock1(i).State = 0 Then
Exit For
End If
Next i
If i > intMax Then
intMax = intMax + 1
Load Winsock1(intMax)
End If
Winsock1(i).Accept requestID
End Sub
tongnaifu 2009-03-10
  • 打赏
  • 举报
回复
这样不行的,要每个客户端建立一个连接
free1688 2009-03-10
  • 打赏
  • 举报
回复
Do While Winsock1.State = sckConnecting
DoEvents
Loop

这在代码中添加了,但是任然有问题,我试过了。
三楼の郎 2009-03-10
  • 打赏
  • 举报
回复
服务器端一个Winsock肯定是不行的,必须要自行设计一个Winsock连接池才能解决1台服务器对多个客户端的通信问题,否则用Winsock控件是实现不了多客户端通讯的。
加载更多回复(4)

1,451

社区成员

发帖
与我相关
我的任务
社区描述
VB 控件
社区管理员
  • 控件
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧