Skip to content

Commit

Permalink
以UDP广播的方式实现了自动连接。
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrysanHua committed Mar 20, 2019
1 parent 3c4e681 commit 9dbd73c
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 40 deletions.
99 changes: 93 additions & 6 deletions Messenger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SocketSingleSend
{
class Messenger
{
class StateObject
{
public Socket workSocket;
public byte[] dataByte;
public IPEndPoint ipe;
}


public const int MAX_BYTE_SIZE = 512;
public const int MIN_BYTE_SIZE = 64;
public const int BROADCAST_INTERVAL = 3000;

private Socket socket;

Expand Down Expand Up @@ -101,10 +112,10 @@ public bool UDPSend(byte[] strByte, EndPoint targetIPE, bool firstSend = true)
return true;
}
}
catch (Exception ex)
catch (SocketException ex)
{
#if DEBUG
Console.WriteLine(ex.Message);
Console.WriteLine(ex.Message + " errorCode: " + ex.ErrorCode);
#endif
}
return false;
Expand All @@ -128,6 +139,53 @@ public bool SteadySend(string str, EndPoint targetIPE)
return false;
}

private void BroadcastCallback(IAsyncResult ar)
{
StateObject stateObj = (StateObject)ar.AsyncState;
try
{
int sendLen = stateObj.workSocket.EndSendTo(ar);
#if DEBUG
Console.WriteLine("<<<<<<<<send one broadcast");
#endif
if (sendLen == stateObj.dataByte.Length)
Thread.Sleep(BROADCAST_INTERVAL);
stateObj.workSocket.BeginSendTo(stateObj.dataByte, 0, stateObj.dataByte.Length,
SocketFlags.None, stateObj.ipe, BroadcastCallback, stateObj);
}
catch (SocketException ex)
{
#if DEBUG
Console.WriteLine(ex.Message + " errorCode: " + ex.ErrorCode);
#endif
}
}

public void Broadcasting(string bcStr, int bc_port)
{
if (!socket.EnableBroadcast)
socket.EnableBroadcast = true;
byte[] bcByte = CryptoUtil.StrToByte(CryptoUtil.Encrypt(bcStr));
IPEndPoint bcIPE = new IPEndPoint(IPAddress.Broadcast, bc_port);
StateObject stateObj = new StateObject()
{
dataByte = bcByte,
ipe = bcIPE,
workSocket = socket
};
try
{
socket.BeginSendTo(bcByte, 0, bcByte.Length, SocketFlags.None,
bcIPE, new AsyncCallback(BroadcastCallback), stateObj);
}
catch (SocketException ex)
{
#if DEBUG
Console.WriteLine(ex.Message + " errorCode: " + ex.ErrorCode);
#endif
}
}


public byte[] UDPReceive(ref EndPoint remoteIPE, int byteSize)
{
Expand Down Expand Up @@ -155,17 +213,18 @@ public byte[] UDPReceive(ref EndPoint remoteIPE, int byteSize)
byte[] remainByte = UDPReceive(ref remoteIPE, remainLen);
IPAddress afterIP = ((IPEndPoint)remoteIPE).Address;
if (!beforeIP.Equals(afterIP))
throw new Exception("Information confusion between different senders");
throw new Exception(
"Information confusion between different senders");
else
strByte = ConcatByte(strByte, remainByte);
}
return strByte;
}
}
catch (Exception ex)
catch (SocketException ex)
{
#if DEBUG
Console.WriteLine(ex.Message);
Console.WriteLine(ex.Message + " errorCode: " + ex.ErrorCode);
#endif
}
return null;
Expand Down Expand Up @@ -232,7 +291,35 @@ public void FlushReceiveBuf()
}
}


public string ReceiveBroadcast(ref EndPoint remoteIPE)
{
if (!socket.EnableBroadcast)
socket.EnableBroadcast = true;
try
{
int byteSize = (MAX_BYTE_SIZE < MIN_BYTE_SIZE) ? MIN_BYTE_SIZE : MAX_BYTE_SIZE;
byte[] receiveByte = new byte[byteSize];
int receiveLen = socket.ReceiveFrom(receiveByte,
SocketFlags.None, ref remoteIPE);
if (receiveLen > 0)
{
string bcMsg = CryptoUtil.Decrypt(CryptoUtil.ByteToStr(
receiveByte, receiveLen));
#if DEBUG
Console.WriteLine(">>>>>>>>get broadcast '{0}' from: {1}",
bcMsg, remoteIPE);
#endif
return bcMsg;
}
}
catch (SocketException ex)
{
#if DEBUG
Console.WriteLine(ex.Message + " errorCode: " + ex.ErrorCode);
#endif
}
return null;
}


}
Expand Down
54 changes: 20 additions & 34 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -20,10 +18,7 @@ class Program
private const int AS_PORT = 11019;
private const int BC_PORT = 19019;
static readonly IPAddress localIP = Dns.GetHostAddresses(Dns.GetHostName()).Last();
//实现加密广播自动连接 Ipv4
//实现不定长数据发送
//重构 抽出Socket通信类
//answer使用hash值作对比

static bool sendFail = true;
static Messenger udpSender;
static Messenger udpReceiver;
Expand Down Expand Up @@ -60,58 +55,47 @@ static EndPoint CreateEmptyEP()

static void Main(string[] args)
{
//while (true)
//{
// string str = Console.ReadLine();
// string key = "SimpleSocketChat";
// //string iv = key;
// //CryptoUtil.Init(key, iv);
// //string enStr = CryptoUtil.Encrypt(str);
// //Console.WriteLine(enStr);
// //string deStr = CryptoUtil.Decrypt(enStr);
// //Console.WriteLine(deStr);
// //string hashStr = CryptoUtil.SHA256Hash(str);
// //Console.WriteLine(hashStr);
// byte[] a = CryptoUtil.StrToByte(str);
// byte[] b = CryptoUtil.StrToByte(key);
// b = Messenger.ConcatByte(a, b);
// a = Messenger.SplitByte(b, a.Length, out b);
// Console.WriteLine(CryptoUtil.ByteToStr(a));
// Console.WriteLine(CryptoUtil.ByteToStr(b));
// Console.WriteLine("-----------------------------");
//}



Console.WriteLine("1. Send ;\r\n2. Receive ;");
#if DEBUG
Console.WriteLine("3. Loop Send ;");
#endif
Console.WriteLine("Make a choice to do(1 or 2):");

string choice = Console.ReadLine();
string choice = Console.ReadLine().Trim();
if (choice == "1")
{
//do Send
InitMessenger(true, true);
IPAddress targetIP = null;
while (targetIP == null)
{
Console.WriteLine("Enter the other side's IP:");
targetIP = StrToIP(Console.ReadLine().Trim());
Console.WriteLine("Enter the other side's IP or press Enter directly:");
string ipStr = Console.ReadLine().Trim();
if (string.IsNullOrEmpty(ipStr))
{
Console.WriteLine("Waiting to auto connect...");
EndPoint remoteIPE = CreateEmptyEP();
ipStr = broadcaster.ReceiveBroadcast(ref remoteIPE);
if (ipStr != null && ipStr.StartsWith(IP_FLAG))
ipStr = ipStr.Substring(IP_FLAG.Length);
}
targetIP = StrToIP(ipStr);
}
Console.WriteLine("Connect to Receiver: {0}", targetIP);
Console.WriteLine("Write down your text:");
Console.WriteLine("-----------------------------------");
string str = null;
do
{
str = Console.ReadLine();
if (str.Length > MAX_STR_LEN)
if (str == null)
break;
else if (str.Length > MAX_STR_LEN)
{
Console.WriteLine("<<<<<<<<<<<Too Long!");
continue;
}
if (str.Length == 0)
else if (str.Length == 0)
{
Console.WriteLine("<<<<<<<<<<<Can not be empty!");
continue;
Expand All @@ -126,6 +110,7 @@ static void Main(string[] args)
InitMessenger(true, false);
Console.WriteLine("Local IP is: " + localIP);
Console.WriteLine("Waiting to receive the Msg...");
broadcaster.Broadcasting(IP_FLAG + localIP, BC_PORT);
Console.WriteLine("-----------------------------------");
string msg = null;
do
Expand Down Expand Up @@ -159,6 +144,7 @@ static void Main(string[] args)
}
}
#endif
broadcaster?.Close();
udpReceiver?.Close();
udpSender?.Close();
}
Expand Down

0 comments on commit 9dbd73c

Please sign in to comment.