商定协议如下:
客户端发送单个字符'p’,服务器接收到'p'后,将'p'返回给客户端,然后客户端发送4个字节的参数码给
服务器,服务器接收到参数后返回字符'b',客户端发送结束字符'f'给服务器,服务器接收到'f',回发字
符'f'给客户端,通信结束;现在出现问题是:服务器三次回发给客户端的字符'p','b','f',但客户端接收到得字符出错了,却是三个'p'。客户端网络实现代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;using System.Net;
using System.Net.Sockets;
using System.Threading;
using Network.DataStruct;
namespace Network {
class TcpClient {
private Socket _Socket = null;
private IPEndPoint ipEndPoint = null; public string retMsg = null; //接收回传数据
public byte[] buffer = new byte[4]; //发送与接收的缓冲区
/*
* 构造函数
*/
public TcpClient(IPContext _ipContext) {
InitSocket(_ipContext.ip, _ipContext.port);
} public TcpClient(IPAddress _ip,int _port) {
InitSocket(_ip, _port);
} /*
* 初始化Socket
*/
private void InitSocket(IPAddress _ip, int _port) {
ipEndPoint = new IPEndPoint(_ip, _port);
_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_Socket.SendTimeout = 2000;
_Socket.ReceiveTimeout = 3000;
_Socket.ReceiveBufferSize = 1;
}
/*
* 连接初始化后的_Socket
* 连接成功返回true
* 连接失败返回false
*/
public bool TcpConnect(){
try {
_Socket.Connect(ipEndPoint);
} catch(SocketException se) {
Console.WriteLine(" SocketException : {0}", se.ToString());
return false;
} catch (Exception e) {
Console.WriteLine(e.ToString());
return false;
} return true;
} /*
* 发送msg字符串到_Socket连接的端点
*
*/
public bool TcpSend(string msg) {
do {
try {
if (_Socket.Poll(50, SelectMode.SelectWrite)) {
/*
*检测网络是否能够被写(即能否发送)
*正确直行Send函数
*不正确程序睡眠100ms,继续检测
*该函数陷入不会死循环
*/
int bytesSent = _Socket.Send(Encoding.ASCII.GetBytes(msg));
Console.WriteLine(" TcpSend --> Send Message : {0}", msg.ToString());
if (bytesSent > 0) break;
}
} catch (Exception e) {
Console.WriteLine(" TcpSend --> Network connection is break ,{0}",e.ToString());
return false;
}
Thread.Sleep(100);
} while (true);
return true;
} public bool TcpSend(byte[] msg) {
do {
try {
if (_Socket.Poll(50, SelectMode.SelectWrite)) {
/*
*检测网络是否能够被写(即能否发送)
*正确直行Send函数
*不正确程序睡眠100ms,继续检测
*该函数陷入不会死循环
*/
int bytesSent = _Socket.Send(msg);
for(int i = 0;i < msg.Length;i ++)
Console.WriteLine(" TcpSend --> Send Message : "+ msg[i]);
if (bytesSent > 0) break;
}
} catch (Exception e) {
Console.WriteLine(" TcpSend --> Network connection is break ,{0}", e.ToString());
return false;
}
Thread.Sleep(100);
} while (true);
return true;
} public bool TcpSend(byte _msg) {
byte[] msg = new byte[1];
msg[0] = _msg;
do {
try {
if (_Socket.Poll(50, SelectMode.SelectWrite)) {
/*
*检测网络是否能够被写(即能否发送)
*正确直行Send函数
*不正确程序睡眠100ms,继续检测
*该函数陷入不会死循环
*/
int bytesSent = _Socket.Send(msg);
for (int i = 0; i < msg.Length; i++)
Console.WriteLine(" TcpSend --> Send Message : " + msg[i]);
if (bytesSent > 0) break;
}
} catch (Exception e) {
Console.WriteLine(" TcpSend --> Network connection is break ,{0}", e.ToString());
return false;
}
Thread.Sleep(100);
} while (true);
return true;
} /*
* 从已经初始化完成的_Socket中,获取已接收到得字符串
*/
public bool TcpReceive() {
int TimeOut = 0;
do {
Thread.Sleep(100);
try {
if (_Socket.Poll(50, SelectMode.SelectRead)) {
/*
*检测网络是否能够被写(即能否发送)
*正确直行Send函数
*不正确程序睡眠100ms,继续检测
*该函数陷入死循环可能性极小,情况如下:
*在100ms内,信号机回传了
*/
int bytesRecv = _Socket.Receive(buffer);
if (bytesRecv > 0) {
retMsg = Encoding.ASCII.GetString(buffer);
dtLog.Log(" TcpReceive --> Recv Message :" + (_Socket.RemoteEndPoint as IPEndPoint).Address.ToString() + buffer[0] +" len : "+ bytesRecv.ToString());
break;
}
}
} catch (Exception e) {
Console.WriteLine(" TcpReceive --> Network connection is break ,{0}",e.ToString());
return false;
}
if (++TimeOut >= 19) return false; //超时设置2秒
} while (true);
return true;
} public bool TcpEnd() {
try {
_Socket.Shutdown(SocketShutdown.Both);
_Socket.Close();
}catch(Exception e){
Console.WriteLine(" TcpEnd --> Network connection is break ,{0}",e.ToString());
return false;
}
return true;
} public bool TcpTestConnect() {
return _Socket.Connected;
} }
}逻辑代码:private void ParameterCommand(TcpClient _TcpClient, IPContext _ipContext) {
byte[] data = { 0x0D, 0x0B, 0x1B, 0x0B, 0x02, 0x23};
//string data = "141127110235";
int i = 0;
_TcpClient.TcpConnect();
_TcpClient.TcpSend("p");
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x70)) { //接收到返回的‘p’
_TcpClient.buffer[0] = 0xff;
_TcpClient.TcpSend(data);
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x62)) { //接收到返回的‘b’
Console.WriteLine("buf[1] : " + _TcpClient.buffer[2]);
_TcpClient.buffer[0] = 0xff;
_TcpClient.TcpSend("f");
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x66)) { //接收到返回的‘f’
Console.WriteLine("buf[2] : " + _TcpClient.buffer[3]);
Console.WriteLine("通信结束:" + _TcpClient.buffer[0]);
//return;
}
} else {
Console.WriteLine("没有等待返回的'b',返回值为:" + _TcpClient.buffer[0]);
}
} else {
Console.WriteLine("没有等待返回的'p',返回值为:" + _TcpClient.buffer[0]);
}
}
我猜测是不是TCP的缓冲区没有改变,一直保存的是第一次接收的字符'p'!!求各位给点建议啊!谢谢
客户端发送单个字符'p’,服务器接收到'p'后,将'p'返回给客户端,然后客户端发送4个字节的参数码给
服务器,服务器接收到参数后返回字符'b',客户端发送结束字符'f'给服务器,服务器接收到'f',回发字
符'f'给客户端,通信结束;现在出现问题是:服务器三次回发给客户端的字符'p','b','f',但客户端接收到得字符出错了,却是三个'p'。客户端网络实现代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;using System.Net;
using System.Net.Sockets;
using System.Threading;
using Network.DataStruct;
namespace Network {
class TcpClient {
private Socket _Socket = null;
private IPEndPoint ipEndPoint = null; public string retMsg = null; //接收回传数据
public byte[] buffer = new byte[4]; //发送与接收的缓冲区
/*
* 构造函数
*/
public TcpClient(IPContext _ipContext) {
InitSocket(_ipContext.ip, _ipContext.port);
} public TcpClient(IPAddress _ip,int _port) {
InitSocket(_ip, _port);
} /*
* 初始化Socket
*/
private void InitSocket(IPAddress _ip, int _port) {
ipEndPoint = new IPEndPoint(_ip, _port);
_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_Socket.SendTimeout = 2000;
_Socket.ReceiveTimeout = 3000;
_Socket.ReceiveBufferSize = 1;
}
/*
* 连接初始化后的_Socket
* 连接成功返回true
* 连接失败返回false
*/
public bool TcpConnect(){
try {
_Socket.Connect(ipEndPoint);
} catch(SocketException se) {
Console.WriteLine(" SocketException : {0}", se.ToString());
return false;
} catch (Exception e) {
Console.WriteLine(e.ToString());
return false;
} return true;
} /*
* 发送msg字符串到_Socket连接的端点
*
*/
public bool TcpSend(string msg) {
do {
try {
if (_Socket.Poll(50, SelectMode.SelectWrite)) {
/*
*检测网络是否能够被写(即能否发送)
*正确直行Send函数
*不正确程序睡眠100ms,继续检测
*该函数陷入不会死循环
*/
int bytesSent = _Socket.Send(Encoding.ASCII.GetBytes(msg));
Console.WriteLine(" TcpSend --> Send Message : {0}", msg.ToString());
if (bytesSent > 0) break;
}
} catch (Exception e) {
Console.WriteLine(" TcpSend --> Network connection is break ,{0}",e.ToString());
return false;
}
Thread.Sleep(100);
} while (true);
return true;
} public bool TcpSend(byte[] msg) {
do {
try {
if (_Socket.Poll(50, SelectMode.SelectWrite)) {
/*
*检测网络是否能够被写(即能否发送)
*正确直行Send函数
*不正确程序睡眠100ms,继续检测
*该函数陷入不会死循环
*/
int bytesSent = _Socket.Send(msg);
for(int i = 0;i < msg.Length;i ++)
Console.WriteLine(" TcpSend --> Send Message : "+ msg[i]);
if (bytesSent > 0) break;
}
} catch (Exception e) {
Console.WriteLine(" TcpSend --> Network connection is break ,{0}", e.ToString());
return false;
}
Thread.Sleep(100);
} while (true);
return true;
} public bool TcpSend(byte _msg) {
byte[] msg = new byte[1];
msg[0] = _msg;
do {
try {
if (_Socket.Poll(50, SelectMode.SelectWrite)) {
/*
*检测网络是否能够被写(即能否发送)
*正确直行Send函数
*不正确程序睡眠100ms,继续检测
*该函数陷入不会死循环
*/
int bytesSent = _Socket.Send(msg);
for (int i = 0; i < msg.Length; i++)
Console.WriteLine(" TcpSend --> Send Message : " + msg[i]);
if (bytesSent > 0) break;
}
} catch (Exception e) {
Console.WriteLine(" TcpSend --> Network connection is break ,{0}", e.ToString());
return false;
}
Thread.Sleep(100);
} while (true);
return true;
} /*
* 从已经初始化完成的_Socket中,获取已接收到得字符串
*/
public bool TcpReceive() {
int TimeOut = 0;
do {
Thread.Sleep(100);
try {
if (_Socket.Poll(50, SelectMode.SelectRead)) {
/*
*检测网络是否能够被写(即能否发送)
*正确直行Send函数
*不正确程序睡眠100ms,继续检测
*该函数陷入死循环可能性极小,情况如下:
*在100ms内,信号机回传了
*/
int bytesRecv = _Socket.Receive(buffer);
if (bytesRecv > 0) {
retMsg = Encoding.ASCII.GetString(buffer);
dtLog.Log(" TcpReceive --> Recv Message :" + (_Socket.RemoteEndPoint as IPEndPoint).Address.ToString() + buffer[0] +" len : "+ bytesRecv.ToString());
break;
}
}
} catch (Exception e) {
Console.WriteLine(" TcpReceive --> Network connection is break ,{0}",e.ToString());
return false;
}
if (++TimeOut >= 19) return false; //超时设置2秒
} while (true);
return true;
} public bool TcpEnd() {
try {
_Socket.Shutdown(SocketShutdown.Both);
_Socket.Close();
}catch(Exception e){
Console.WriteLine(" TcpEnd --> Network connection is break ,{0}",e.ToString());
return false;
}
return true;
} public bool TcpTestConnect() {
return _Socket.Connected;
} }
}逻辑代码:private void ParameterCommand(TcpClient _TcpClient, IPContext _ipContext) {
byte[] data = { 0x0D, 0x0B, 0x1B, 0x0B, 0x02, 0x23};
//string data = "141127110235";
int i = 0;
_TcpClient.TcpConnect();
_TcpClient.TcpSend("p");
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x70)) { //接收到返回的‘p’
_TcpClient.buffer[0] = 0xff;
_TcpClient.TcpSend(data);
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x62)) { //接收到返回的‘b’
Console.WriteLine("buf[1] : " + _TcpClient.buffer[2]);
_TcpClient.buffer[0] = 0xff;
_TcpClient.TcpSend("f");
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x66)) { //接收到返回的‘f’
Console.WriteLine("buf[2] : " + _TcpClient.buffer[3]);
Console.WriteLine("通信结束:" + _TcpClient.buffer[0]);
//return;
}
} else {
Console.WriteLine("没有等待返回的'b',返回值为:" + _TcpClient.buffer[0]);
}
} else {
Console.WriteLine("没有等待返回的'p',返回值为:" + _TcpClient.buffer[0]);
}
}
我猜测是不是TCP的缓冲区没有改变,一直保存的是第一次接收的字符'p'!!求各位给点建议啊!谢谢
解决方案 »
- C# DataTableAdapter 如何获取带参数的SQL语句
- 循环结构中的问题
- 【求助】在c/s程序中,每当连入一个客户端,就在treeview中添加一个节点
- C#在读取XML时,怎样区别注释行呢?
- 数据库连接不上
- 怎摸在TREEVIEW的根节点的后面动态加栽一个TextBox控件
- C# socket 异步服务端丢失数据
- C#: winform--DataGrid 中为什么不能回车?
- 同样的SQL语句在XP系统里不执行,为何?
- 怎样调试一个Assembly Dll
- |ZYCWPF| RTP发送数据的时候能不能指定端口的实例?因为我可能同一端口同时会接收多个流实例 谢谢
- 如何将str1分离出3个字符串
_TcpClient.TcpSend("p");
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x70)) { //接收到返回的‘p’
_TcpClient.buffer[0] = 0xff;
_TcpClient.TcpSend(data);
//这里写清空缓存
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x62)) { //接收到返回的‘b’
Console.WriteLine("buf[1] : " + _TcpClient.buffer[2]);
_TcpClient.buffer[0] = 0xff;
_TcpClient.TcpSend("f");
//这里写清空缓存
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x66)) { //接收到返回的‘f’
Console.WriteLine("buf[2] : " + _TcpClient.buffer[3]);
Console.WriteLine("通信结束:" + _TcpClient.buffer[0]);
//这里写清空缓存
//return;
byte[] data = { 0x0D, 0x0B, 0x1B, 0x0B, 0x02, 0x23};
//string data = "141127110235";
int step = 0;
//int i = 0;
_TcpClient.TcpConnect(); do {
if (step == 0) { //发送 p 命令
_TcpClient.TcpSend("p");
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x70)) step++;
} else if (step == 1) { //发送数据
_TcpClient.TcpSend(data);
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x62)) step++;
} else if (step == 2) { //发送结束字符
_TcpClient.TcpSend("f");
_TcpClient.TcpReceive();
if (_TcpClient.buffer[0].Equals(0x66)) break;
}
Thread.Sleep(1000);
} while (true);
}
要接收400次左右才能收到字符'b',‘f’,求解释啊!!!?
请问清空缓存,缓存是指自己定义的接收缓存还是系统定义Socket的接收缓存?