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
...全文
237 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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,453

社区成员

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

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