请教一个 socket 的 数据 封装的问题
代码是网上下的:
共两个文件,是客户端的代码,UDP协议发送数据。
[/code]
文件2里的代码:
问题2:
如果第一问题不成立,在第二个文件里,如何准备自己的数据包?
也就是在如下两个函数的哪个函数里,准备自己的数据包合适?
最后一个问题,就这个DEMO的目前方式,,如何准备自己的数据包,是相对合理的?
共两个文件,是客户端的代码,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的目前方式,,如何准备自己的数据包,是相对合理的?
...全文
相关推荐
C# Socket通讯框架,封装了Client和Server端类库,带实例
C# Socket通讯框架,封装了Client和Server端类库,带演示实例和使用手册.
封装Socket
Socket使用,此demo为Socket封装,含有一些简单处理粘包问题的办法
C# socket封装类和组件含例程全部开源
C# socket封装类和组件含例程全部开源,可以说全网封装最好的C#类,十分强大,亲测很好,值得参考和学习
一个封装良好的SOCKET通信类
通过重新整理,打造了一个SOCKET封装类,能够高效的完成目前的通信问题,只需直接调用即可。
C# Socket 客户端服务端封装带使用实例
Socket 客户端代码封装、服务端代码封装,让使用Socket更简单,队列处理,带使用实例。


