发送的报文头信息为Struct类型,发送数据类型可以是String 也可以是一个类。在发送Struct类型或发送类时,必须先将这个类序列化为流,接收时再将流反序列化为对象。接收的缓冲区大小设为1024,先接收报文头,再根据报文头中发送数据的长度来接收数据(当然,也可以开一个很大的缓冲区来接数据,但可能会比较浪费资源)。
1、发送的方法。
在调用这个方法时,需要在实例化类时传入两个参数:目标IP和目标计算机的监听端口号。
public int CMSend(Object tcpHeader, Object objData, int outTime)
{
int flag = 0;
try
{
StartClient();
TcpHead structHead = (TcpHead)tcpHeader;
byte[] btyData = null;
byte[]
btySendHead = new byte[32];
string strData =
string.Empty;
switch (structHead.MessageType)
{
case "String":
strData =
objData.ToString();
btyData =
Encoding.ASCII.GetBytes(strData);
structHead.MessageLength = strData.Length;
break;
case
"BaseDataContainer":
btyData =
TransDataToByteArray(objData,
BasePage.enumParamType.BaseDataContainer.ToString());
structHead.MessageLength = btyData.Length;
break;
default:
break;
}
btySendHead = TransDataToByteArray(structHead, BasePage.enumParamType.Struct.ToString());
byte[] bytSendData = new byte[btySendHead.Length + btyData.Length];
btySendHead.CopyTo(bytSendData, 0);
btyData.CopyTo(bytSendData, btySendHead.Length);
if (m_clientSocket == null || m_clientSocket.Connected ==
false)
{
throw new
ArgumentException("參數socket 為null,或者未連接到遠程計算機");
}
if (bytSendData == null || bytSendData.Length ==
0)
{
throw new
ArgumentException("參數buffer 為null ,或者長度為 0");
}
int left = bytSendData.Length;
int
sndLen = 0;
while (true)
{
if ((m_clientSocket.Poll(outTime * 1000000, SelectMode.SelectWrite) == true))//
收集了足够多的傳出數據后開始發送
{
sndLen =
this.m_clientSocket.Send(bytSendData, sndLen, left,
SocketFlags.None);
left -=
sndLen;
if (left == 0)
{ //
數據已經全部發送
flag =
0;
break;
}
else
{
if (sndLen >
0)
{ //
數據已經部分被發送
continue;
}
else
{ //
發送數據發生錯誤
flag =
-2;
break;
}
}
}
else
{ //
超時退出
flag = -1;
break;
}
}
}
catch (System.NullReferenceException
e)
{
MessageBox.Show("連接失敗", "INF:001",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception e)
{
MessageBox.Show("發送失敗", "INF:001", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
finally
{
this.close();
}
return flag;
}
2、接收方法
在调用这个方法时,需要在实例化类时传入一个参数:本地的监听端口号。
public Hashtable CMReceive()
{
if (firstFlag ==
true)
{
tcpListener = new
TcpListener(receivePort);
tcpListener.Start();
firstFlag = false;
}
while (true)
{
listenSocket
= tcpListener.AcceptSocket();
string strTcpHead = string.Empty;
byte[] bytTcpHead = new byte[1024];
byte[] receiveByte = new byte[1024];
byte[] bytReceiveData =
null;
TcpHead structReceiveHead;
object
objStructReceiveHead;
int bytes = 0;
int count =
0;
int messageLength;
int
buffLength;
bool isHead = true;
while (true)
{
bytes = listenSocket.Receive(receiveByte, receiveByte.Length,
SocketFlags.None);
bytTcpHead =
receiveByte;
isHead = false;
break;
}
objStructReceiveHead =
TransByteArrayToObject(bytTcpHead,
BasePage.enumParamType.Struct.ToString());
structReceiveHead
= (TcpHead)objStructReceiveHead;
messageLength = structReceiveHead.MessageLength;
if (messageLength % 1024 == 0)
{
buffLength = messageLength / 1024;
}
else
{
buffLength = messageLength / 1024 + 1;
}
if (count == 0)
{
bytReceiveData =
new byte[buffLength * 1024];
}
while (true)
{
bytes = listenSocket.Receive(receiveByte, receiveByte.Length,
SocketFlags.None);
if (bytes <=
0)
break;
receiveByte.CopyTo(bytReceiveData, count * 1024);
count++;
}
object objReceiveData = TransByteArrayToObject(bytReceiveData, structReceiveHead.MessageType);
Hashtable htTcpHead = new Hashtable();
htTcpHead.Add("objStructReceiveHead",
structReceiveHead);
htTcpHead.Add("objReceiveData",
objReceiveData);
return htTcpHead;
}
}
3、把对象转化为字节流的方法
public byte[] TransDataToByteArray(Object objectParam, string
sendDataType)
{
BinaryFormatter bf = new
BinaryFormatter();
MemoryStream memoryStream = new
MemoryStream();
byte[] buff = null;
switch (sendDataType)
{
case
"String":
string tempStr =
objectParam.ToString();
Char[] tempChar =
tempStr.ToCharArray();
buff =
System.Text.Encoding.UTF8.GetBytes(tempChar);
break;
case "BaseDataContainer":
bf.Serialize(memoryStream, objectParam);
buff =
memoryStream.ToArray();
break;
case
"Struct":
bf.Serialize(memoryStream,
objectParam);
byte[] tempByte =
memoryStream.ToArray();
buff = new Byte[1024];
tempByte.CopyTo(buff, 0);
for (int k = tempByte.Length; k < 1024;
k++)
{
buff.SetValue(Byte.Parse("1"), k);
}
break;
default:
break;
}
return buff;
}
4、把字节流反转为对象的方法
public object TransByteArrayToObject(byte[] byteTemp, string
paramType)
{
if
(paramType.Equals("String"))
{
string object_temp =
System.Text.Encoding.UTF8.GetString(byteTemp);
return
object_temp;
}
else if
(paramType.Equals("BaseDataContainer"))
{
MemoryStream memoryStream = new MemoryStream(byteTemp);
BinaryFormatter bf = new BinaryFormatter();
BaseDataContainer object_temp =
(BaseDataContainer)bf.Deserialize(memoryStream);
return object_temp;
}
else
if (paramType.Equals("Struct"))
{
MemoryStream memoryStream = new MemoryStream(byteTemp);
BinaryFormatter bf = new BinaryFormatter();
TcpHead
object_temp = (TcpHead)bf.Deserialize(memoryStream);
return
object_temp;
}
else
{
return "Exception";
}
}
5、获取本地IP
#region 取得本地IP
public string GetHostIP()
{
string strHostname = Dns.GetHostName();
IPHostEntry strIP = Dns.GetHostEntry(strHostname);
string
localIPStr = strIP.AddressList[0].ToString();
IPAddress localIP
= IPAddress.Parse(localIPStr);
return localIPStr;
}
#endregion
6、连接目标计算机
public void StartClient()
{
//Connect to a remote
device.
try
{
IPHostEntry
ipHostInfo = Dns.Resolve(this.m_strServerIP);
IPAddress
ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP =
new IPEndPoint(ipAddress, this.m_nServerPort);
//Create a TCP/IP socket.
this.m_clientSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
//Connect to the remote endpoint.
if
(m_clientSocket.Connected)
{
close();
}
this.m_clientSocket.Connect(remoteEP);
}
catch
(Exception e)
{
this.ReportError("StartClient found a error:/r/n" +
e.ToString());
}
}

856

被折叠的 条评论
为什么被折叠?



