请教一个 socket 的 数据 封装的问题

色郎中 色郎中 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
代码是网上下的:
共两个文件,是客户端的代码,UDP协议发送数据。



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);
}


[/code]

文件2里的代码:

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);
}

}
}

问题2:
如果第一问题不成立,在第二个文件里,如何准备自己的数据包?
也就是在如下两个函数的哪个函数里,准备自己的数据包合适?
  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);
}



最后一个问题,就这个DEMO的目前方式,,如何准备自己的数据包,是相对合理的?
...全文
评论 1
收藏 已收藏
分享
返回顶部
色郎中
C# 111,129 成员 642,540 内容