1. 客户端和服务器Socket都使用 BeginXXX和EndXXX。
2. 设置一个Form1类型变量myForm1,当窗体Form1加载时将其this指针赋值给myForm1。
3. 当接收完毕后,调用Form1的成员函数 进行显示。需要注意,在Form1的成员函数中,如果需要用到Form1的控件,则需要使用委托。
4. 数据格式转化
(1)String 转 byte[ ]
byte[ ] bytesToSend = Encoding.UTF8.GetBytes(textBoxSend.Text);
(2)byte[ ] 转 String
string strText = Encoding.UTF8.GetString(recvBytes);
(3)String 转 byte[ ],如“123456”转为{0x12, 0x34, 0x56}
private byte[] HexStringToBytes(string hexString)
{
string str = hexString;
if(hexString.Length%2 != 0)
str = hexString.Substring(0,hexString.Length - 1);
int byteLength = str.Length / 2;
byte[] bytes = new byte[byteLength];
int bytesIndex = 0;
for (int strIndex = 0; bytesIndex < bytes.Length; bytesIndex++, strIndex = strIndex + 2)
{
string hex = new String(new Char[]{str[strIndex], str[strIndex + 1]});
byte[] b = BitConverter.GetBytes(int.Parse(hex,System.Globalization.NumberStyles.AllowHexSpecifier));
bytes[bytesIndex] = b[0];
}
return bytes;
}
(4)byte[ ] 转 String, 如{0x12, 0x34, 0x56}转为“123456”
private string BytesToHexString(byte[] bytes) // 0xae00cf => "AE00CF "
{
string hexString = string.Empty;
if (bytes != null)
{
StringBuilder strB = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
strB.Append(bytes[i].ToString("X2"));
}
hexString = strB.ToString();
}
return hexString;
}
5. 客户端Connect函数
public void Connect(EndPoint remoteEP)
{
Console.WriteLine("Connecting server...");
try
{
if (client == null)
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
if (!client.Connected)
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
}
catch (System.Exception e) //一般网络异常触发
{
Console.WriteLine("Net Error");
if (client != null)
{
client.Close();
client = null; //在此需要赋值null
}
}
}
6. 服务器端
(1)listen
public void StartListening()
{
// Establish the local endpoint for the socket.
IPEndPoint localEndPoint = GetIPEndPoint();
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
(2)AcceptCallback函数
当有客户端连接时触发,在此维护客户端Socket和其唯一标识Id的List
(3)当客户端Socket关闭 或出现网络异常时,ReadCallback方法中的
int bytesRead = handler.EndReceive(ar)会引发异常,在异常处理中关闭对应Socket并维护LIst
(4)send出现异常时,只要捕捉异常并进行相关提示就可以了,不用在此修改LIst