110,536
社区成员
发帖
与我相关
我的任务
分享
namespace SocketUdpClient
{
class Program
{
static string serverIp;
static string name = string.Empty;
static int port1,port2;
static UdpClient client;
static void Main(string[] args)
{
Console.WriteLine("输入服务器IP地址");
serverIp = Console.ReadLine();
Console.WriteLine("输入接入端口");
port1 = int.Parse(Console.ReadLine());
Console.WriteLine("输入通信端口");
port2 = int.Parse(Console.ReadLine());
while (running()) ;
Console.ReadKey();
}
static bool running()
{
int txtNum;
Console.WriteLine("输入最大连接数");
txtNum = int.Parse(Console.ReadLine());
client = new UdpClient(port1, port2, serverIp, txtNum);
for (int i = 0; i < txtNum; i++)
{
client.Start();
Thread.Sleep(30);
}
return txtNum > 0;
}
}
}
第一个问题是:
在文件1里的如下代码 .start(),开始传入要发送的数据包可以不?
如果可以,在文件2里,start()函数如何封装?
[code=csharp]
for (int i = 0; i < txtNum; i++)
{
client.Start();
Thread.Sleep(30);
}
namespace SocketUdpClient
{
public class UdpClient
{
/// <summary>
/// 连接请求地址
/// </summary>
IPEndPoint remoteAccpetPort;
/// <summary>
/// 数据通信地址
/// </summary>
IPEndPoint remoteCommunicationPort;
private SocketAsyncEventArgsPool pool;
private BufferManager bfManager;
private int bufferSize = 1024;
Random r = new Random();
/// <summary>
///
/// </summary>
/// <param name="port1">第一次通讯端口,用于确认连接</param>
/// <param name="port2">数据通信端口</param>
/// <param name="ServerIP">服务器IP地址</param>
public UdpClient(int port1,int port2,string ServerIP,int numClient)
{
remoteAccpetPort = new IPEndPoint(IPAddress.Parse(ServerIP), port1);
remoteCommunicationPort = new IPEndPoint(IPAddress.Parse(ServerIP), port2);
pool = new SocketAsyncEventArgsPool(numClient);
bfManager = new BufferManager(numClient * bufferSize * 2, bufferSize);
bfManager.InitBuffer();
SocketAsyncEventArgs args;
for (int i = 0; i < numClient; i++)
{
args = new SocketAsyncEventArgs();
args.Completed += new EventHandler<SocketAsyncEventArgs>(args_Completed);
bfManager.SetBuffer(args);
pool.Push(args);
}
}
void args_Completed(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation .SendTo :
ProcessSent(e);
break;
default:
throw new ArgumentException("The last operation completed on the socket was not a send");
}
}
public void Start()
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
SocketAsyncEventArgs args = pool.Pop();
args.RemoteEndPoint = remoteAccpetPort;
args.UserToken = socket;
StartSend(args);
}
private void StartSend(SocketAsyncEventArgs args)
{
Socket socket = args.UserToken as Socket;
if(!socket.SendToAsync(args))
{
ProcessSent(args);
}
}
void ProcessSent(SocketAsyncEventArgs e)
{
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
e.RemoteEndPoint = remoteCommunicationPort;
}
Thread.Sleep(1000);
StartSend(e);
}
}
}
private void StartSend(SocketAsyncEventArgs args)
{
Socket socket = args.UserToken as Socket;
if(!socket.SendToAsync(args))
//发现程序执行到这句时,发送数据包到服务器端了。
// 另外发现一个问题,这里自动给服务器端发送了1024个字节的数据,如何准备自己的数据包呢?
// 要自己 给args.Buffer 里赋值?
{
ProcessSent(args);
}
}
void ProcessSent(SocketAsyncEventArgs e)
{
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
e.RemoteEndPoint = remoteCommunicationPort;
}
Thread.Sleep(1000);
StartSend(e);
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="buffer">数据包</param>
/// <param name="any">指定的IP地址与端口</param>
public void Send(byte[] buffer, IPEndPoint any)
{
if (m_Running)
{
try
{
m_Socket.BeginSendTo(
buffer,
0,
buffer.Length,
SocketFlags.None,
any,
new AsyncCallback(AsyncEndSend),
m_Socket);
}
catch (SocketException se)
{
}
}
}