服务端是UNIX C,客户端是vb.net,现把客户端代码贴出来,大家看我看下,该如何改进,才能满足要求。
客户端代码:
Public Class StateObject
'SOCKET ID
Public workSocket As Socket = Nothing
'可接收数据大小
Public Const BufferSize As Integer = 1024 * 512
'Public Const BufferSize As Integer = 1024
'接收数据缓冲区
Public buffer(BufferSize) As Byte
'接收数据
Public sb As New StringBuilder
End Class
Public Class ESA_TCP_CLIENT
'处理结果
Public Enum ExSocketState
ExSocketSucceed = 0 '处理成功
ExSocketNoConnect = 1 '主机无连接
ExSocketUnKnown = 2 '未知状态(主机未响应)
ExSocketAllUsed = 3 '无可用端口(没有空闲状态的端口)
End Enum
Private connectDone As New ManualResetEvent(False)
Private sendDone As New ManualResetEvent(False)
Private receiveDone As New ManualResetEvent(False)
Private response As String = String.Empty
'超时时间(毫秒)
Private iTimeOutM As Integer
Private isConn As Boolean = False
Public Function SendTo(ByVal strHostIP As String, _
ByVal iPort As Integer, _
ByVal iTimeout As Integer, _
ByVal strSend As String, _
ByRef strRecv As String, _
ByVal Merch_ID As String, _
ByVal ULNm As String) As ExSocketState '增加Merch_ID,ULNm zfy 2011-1-6 用于生成Merch_ID.txt文件
On Error GoTo go_Err
Dim ipHostInfo As IPHostEntry = Dns.GetHostEntry(strHostIP)
Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
Dim remoteEP As New IPEndPoint(ipAddress, iPort)
Dim client As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
strRecv = ""
If iTimeout > 0 And iTimeout < 200000 Then '1000000
iTimeOutM = iTimeout
Else
iTimeOutM = 5000 '5000
End If
SendTo = ExSocketState.ExSocketUnKnown
client.BeginConnect(remoteEP, New AsyncCallback(AddressOf ConnectCallback), client)
Dim s2 = Now()
If connectDone.WaitOne(iTimeOutM, False) = True Then
If isConn = True Then
Send(client, strSend, Merch_ID, ULNm) '增加Merch_ID zfy 2011-1-6 用于生成Merch_ID.txt文件
If sendDone.WaitOne(iTimeOutM, False) = True Then
If isConn = True Then
'由于测试中出现异步通讯时接收主机报文有报文不完整情况
'所以在此处修改为在连接、发送时采用异步方式,而接收数据时采用同步方式
'此处还需要考虑同步接收的超时机制,暂略
Dim state As New StateObject
state.workSocket = client
If Receive(state, Merch_ID, ULNm) Then '增加Merch_ID,ULNm zfy 2011-1-6 用于生成Merch_ID.txt文件
'If Receive() Then
strRecv = state.sb.ToString()
If strRecv.Length > 10 Then
strRecv = strRecv.Substring(10, strRecv.Length - 10)
Else
strRecv = ""
End If
SendTo = ExSocketState.ExSocketSucceed
Else
SendTo = ExSocketState.ExSocketUnKnown
End If
Else
SendTo = ExSocketState.ExSocketUnKnown
End If
Else
SendTo = ExSocketState.ExSocketUnKnown
End If
Else
SendTo = ExSocketState.ExSocketNoConnect
End If
Else
SendTo = ExSocketState.ExSocketNoConnect
End If
go_Exit:
If client.Connected = True Then
client.Shutdown(SocketShutdown.Both)
End If
client.Close()
Exit Function
go_Err:
GoTo go_Exit
End Function
Private Sub ConnectCallback(ByVal ar As IAsyncResult)
On Error GoTo go_Err
Dim client As Socket = TryCast(ar.AsyncState, Socket)
If client IsNot Nothing Then
client.EndConnect(ar)
isConn = client.Connected
Else
isConn = False
End If
connectDone.Set()
go_Exit:
Exit Sub
go_Err:
isConn = False
connectDone.Set()
GoTo go_Exit
End Sub
Private Function Receive(ByRef state As StateObject, ByVal Merch_ID As String, ByVal ULNm As String) As Boolean '增加Merch_ID,ULNm zfy 2011-1-6 用于生成Merch_ID.txt文件
On Error GoTo go_Err
Dim readStream As New NetworkStream(state.workSocket)
Dim blnReturn As Boolean = False
Dim intRcv As Integer
Dim strTmp As String = ""
state.buffer.Clear(state.buffer, 0, StateObject.BufferSize)
readStream.ReadTimeout = iTimeOutM
intRcv = readStream.Read(state.buffer, 0, StateObject.BufferSize)
Do While intRcv > 0
strTmp = Encoding.Default.GetString(state.buffer, 0, intRcv)
state.sb.Append(strTmp)
If ConfigurationManager.AppSettings("g_IsDebug") = "1" Then
Dim FileToWrite As System.IO.FileStream = System.IO.File.Create("D:\程序\ESA_OPR_New\debug\Receive" + Merch_ID + "_" + ULNm + ".txt")
Dim rByte() As Byte = Encoding.Default.GetBytes(state.sb.ToString.ToCharArray)
FileToWrite.Write(rByte, 0, rByte.Length)
FileToWrite.Close()
FileToWrite = Nothing
End If
'不按照报文头字符长度来取报文体字段,因为在测试中发现WINDOWS与UNIX在中文和特殊字符的长度判断上不相同
'所以采用查找结束符号的方式来判断报文尾
If InStr(strTmp, "</PACKAGE>") > 0 Then
Exit Do
Else
state.buffer.Clear(state.buffer, 0, StateObject.BufferSize)
intRcv = readStream.Read(state.buffer, 0, StateObject.BufferSize)
End If
Loop
blnReturn = True
readStream = Nothing
go_Exit:
Return blnReturn
Exit Function
go_Err:
blnReturn = False
GoTo go_Exit
End Function
Private Sub Send(ByVal client As Socket, ByVal data As String, ByVal Merch_ID As String, ByVal ULNm As String) '增加Merch_ID,ULNm 2010-1-6 zfy
On Error GoTo go_Err
'2011-7-14 解决中文字符编码数量问题
Dim strLen As Integer
For n = 1 To data.Length
If AscW(Mid(data, n, 1)) > 256 Then strLen = strLen + 2 Else strLen = strLen + 1
Next
data = Format(strLen, "0000000000") & data
If ConfigurationManager.AppSettings("g_IsDebug") = "1" Then
Dim FileToWrite As System.IO.FileStream = System.IO.File.Create("D:\程序\ESA_OPR_New\debug\Send" + Merch_ID + "_" + ULNm + ".txt")
'Dim rByte() As Byte = Encoding.Default.GetBytes(data.ToCharArray)
Dim rByte() As Byte = Encoding.Default.GetBytes(data.ToCharArray)
FileToWrite.Write(rByte, 0, rByte.Length)
FileToWrite.Close()
FileToWrite = Nothing
End If
Dim byteData As Byte() = Encoding.Default.GetBytes(data) '2011-7-15 zfy 解决报文发送乱码问题
client.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), client)
go_Exit:
Exit Sub
go_Err:
GoTo go_Exit
End Sub
Private Sub SendCallback(ByVal ar As IAsyncResult)
On Error GoTo go_Err
Dim client As Socket = TryCast(ar.AsyncState, Socket)
If client IsNot Nothing Then
isConn = True
Dim bytesSent As Integer = client.EndSend(ar)
Else
isConn = False
End If
sendDone.Set()
go_Exit:
Exit Sub
go_Err:
isConn = False
sendDone.Set()
GoTo go_Exit
End Sub
End Class
17 个解决方案
#1
没人知道吗
#2
这里的人气这么低
#3
因为这里是 VB6.0,不是 vb.net
#4
网络编程,socket应该是一样的
#5
你的问题还需要看下服务器端的接受数据的策略,单从客户端无法找到原因的
#6
高手有没有什么好的解决方案
#7
"如果多个用户同时向主机发送数据,则返回结果是错误"
这意味着单个用户访问是没问题的,这意味着单个用户发送是没问题的,看你的代码需要连接,说明是TCP/IP协议,因为每一个TCP/IP协议都是通过一个套接字连接,一个套接字获取或发送数据,如果单个的成功了,也就意味着客户端应该是没问题的,所以从通讯技术上,我认为问题应该出在服务器那边,而不是客户端。
但如果问题出在握手协议或具体数据上,除非你给出握手协议标准和相关算法,否则别人也很难帮你猜问题在哪。还有,你的是一个类,至于出问题的是在过程调用?数据算法?还是握手协议?都很难估计。但单纯以问题出现的情况来看,服务器端的嫌疑最大,你这问题看来还要自己琢磨一下,因为具体的问题出在哪很难帮你去猜。
这意味着单个用户访问是没问题的,这意味着单个用户发送是没问题的,看你的代码需要连接,说明是TCP/IP协议,因为每一个TCP/IP协议都是通过一个套接字连接,一个套接字获取或发送数据,如果单个的成功了,也就意味着客户端应该是没问题的,所以从通讯技术上,我认为问题应该出在服务器那边,而不是客户端。
但如果问题出在握手协议或具体数据上,除非你给出握手协议标准和相关算法,否则别人也很难帮你猜问题在哪。还有,你的是一个类,至于出问题的是在过程调用?数据算法?还是握手协议?都很难估计。但单纯以问题出现的情况来看,服务器端的嫌疑最大,你这问题看来还要自己琢磨一下,因为具体的问题出在哪很难帮你去猜。
#8
哪里有socket通讯教程,看一看,对socket通讯实在不懂,网上搜了一下,没有合适的
#9
向高手们学习了!
#10
#11
#12
提供一种思路,能不能让它们排队先来后到,通过数据排序
#13
7楼学习
#14
并发是否有个队列问题?
并发数量多了,这个队列之外的请求就被丢弃了?就像DDOS一样.
并发数量多了,这个队列之外的请求就被丢弃了?就像DDOS一样.
#15
我想你的服务端处理数据需要时间而客户端发送间隔太短,socket被挂起无法响应新的请求
可能与你的服务端程序有关。
网络并发是一个很有意思的课题。
可能与你的服务端程序有关。
网络并发是一个很有意思的课题。
#16
如果第一个查询有100条数据,需要用时20秒,第二个查询有20条数据,需要用时10秒,则肯定会出错,第一个查询显示没有查到(实际是有数据的100条),第二个查询返回的是第一个查询的结果,也就是两个结果正好相反.如果先查20条数据用时10秒,后查100条数据用时20秒的则两个查询都能返回正确的结果,这是什么原因
#17
#1
没人知道吗
#2
这里的人气这么低
#3
因为这里是 VB6.0,不是 vb.net
#4
网络编程,socket应该是一样的
#5
你的问题还需要看下服务器端的接受数据的策略,单从客户端无法找到原因的
#6
高手有没有什么好的解决方案
#7
"如果多个用户同时向主机发送数据,则返回结果是错误"
这意味着单个用户访问是没问题的,这意味着单个用户发送是没问题的,看你的代码需要连接,说明是TCP/IP协议,因为每一个TCP/IP协议都是通过一个套接字连接,一个套接字获取或发送数据,如果单个的成功了,也就意味着客户端应该是没问题的,所以从通讯技术上,我认为问题应该出在服务器那边,而不是客户端。
但如果问题出在握手协议或具体数据上,除非你给出握手协议标准和相关算法,否则别人也很难帮你猜问题在哪。还有,你的是一个类,至于出问题的是在过程调用?数据算法?还是握手协议?都很难估计。但单纯以问题出现的情况来看,服务器端的嫌疑最大,你这问题看来还要自己琢磨一下,因为具体的问题出在哪很难帮你去猜。
这意味着单个用户访问是没问题的,这意味着单个用户发送是没问题的,看你的代码需要连接,说明是TCP/IP协议,因为每一个TCP/IP协议都是通过一个套接字连接,一个套接字获取或发送数据,如果单个的成功了,也就意味着客户端应该是没问题的,所以从通讯技术上,我认为问题应该出在服务器那边,而不是客户端。
但如果问题出在握手协议或具体数据上,除非你给出握手协议标准和相关算法,否则别人也很难帮你猜问题在哪。还有,你的是一个类,至于出问题的是在过程调用?数据算法?还是握手协议?都很难估计。但单纯以问题出现的情况来看,服务器端的嫌疑最大,你这问题看来还要自己琢磨一下,因为具体的问题出在哪很难帮你去猜。
#8
哪里有socket通讯教程,看一看,对socket通讯实在不懂,网上搜了一下,没有合适的
#9
向高手们学习了!
#10
#11
#12
提供一种思路,能不能让它们排队先来后到,通过数据排序
#13
7楼学习
#14
并发是否有个队列问题?
并发数量多了,这个队列之外的请求就被丢弃了?就像DDOS一样.
并发数量多了,这个队列之外的请求就被丢弃了?就像DDOS一样.
#15
我想你的服务端处理数据需要时间而客户端发送间隔太短,socket被挂起无法响应新的请求
可能与你的服务端程序有关。
网络并发是一个很有意思的课题。
可能与你的服务端程序有关。
网络并发是一个很有意思的课题。
#16
如果第一个查询有100条数据,需要用时20秒,第二个查询有20条数据,需要用时10秒,则肯定会出错,第一个查询显示没有查到(实际是有数据的100条),第二个查询返回的是第一个查询的结果,也就是两个结果正好相反.如果先查20条数据用时10秒,后查100条数据用时20秒的则两个查询都能返回正确的结果,这是什么原因