C# 套接字(TCP 和 UDP)
C# Sockets (TCP & UDP)
我将切入正题,我已经在这个问题上停留了几个小时了。大量 Google 和大量研究,但目前还没有直接的答案。
我有一个客户端和一个为 TCP 编码的服务器,它们运行良好,但是,我希望客户端也能够将 UDP 与服务器一起用于 none - 重要的数据包,例如播放器位置。
截至目前,这是我连接客户端的连接代码。
public void ConnectToServer(){
tcp_client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
tcp_client.Connect(server_ip, server_port);
tcp_stream = new NetworkStream(this.tcp_client);
this.udp_client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
this.udp_client.BeginConnect(IPAddress.Parse(server_ip), server_port,new AsyncCallback(udp_connected), null);
}
现在客户端不是我遇到的问题,因为当我使用 udp.Send(byteArray)
它似乎正在发送,因为它没有抛出任何异常,但服务器本身没有响应接收到的任何数据.
请注意这不是 100% copy/pasted 代码。更改以显示问题所在。
private Socket c;
private UdpClient udp;
private isRunning = true;
public Client(Socket c){
// This was accepted from TcpListener on Main Server Thread.
this.c = c;
this.networkStream = new NetworkStream(this.c);
udp = new UdpClient();
udp.Connect((IPEndPoint)c.RemoteEndPoint);
// Then starts 2 thread for listening, 1 for TCP and 1 for UDP.
}
private void handleUDPTraffic(){
IPEndPoint groupEP = (IPEndPoint)c.RemoteEndPoint;
while (isRunning){
try{
byte[] udp_received = udp.Receive(ref groupEP);
Console.WriteLine("Received UDP Packet Data: " + udp_received.Length);
}catch{
log.ERROR("UDP", "Couldn't Receive Data...");
}
}
}
您可以在同一端口上同时使用 TCP 和 UDP。另见:
Can TCP and UDP sockets use the same port?
下面的示例演示了您可以同时发送和接收 UDP 和 TCP 消息。
也许,您创建的用于侦听传入数据报的 UdpClient 就是问题所在。我建议像您的 TcpListener 一样创建一次。
服务器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TCPUDPServer
{
class Program
{
static void Main(string[] args)
{
TcpListener tcpServer = null;
UdpClient udpServer = null;
int port = 59567;
Console.WriteLine(string.Format("Starting TCP and UDP servers on port {0}...", port));
try
{
udpServer = new UdpClient(port);
tcpServer = new TcpListener(IPAddress.Any, port);
var udpThread = new Thread(new ParameterizedThreadStart(UDPServerProc));
udpThread.IsBackground = true;
udpThread.Name = "UDP server thread";
udpThread.Start(udpServer);
var tcpThread = new Thread(new ParameterizedThreadStart(TCPServerProc));
tcpThread.IsBackground = true;
tcpThread.Name = "TCP server thread";
tcpThread.Start(tcpServer);
Console.WriteLine("Press <ENTER> to stop the servers.");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Main exception: " + ex);
}
finally
{
if (udpServer != null)
udpServer.Close();
if (tcpServer != null)
tcpServer.Stop();
}
Console.WriteLine("Press <ENTER> to exit.");
Console.ReadLine();
}
private static void UDPServerProc(object arg)
{
Console.WriteLine("UDP server thread started");
try
{
UdpClient server = (UdpClient)arg;
IPEndPoint remoteEP;
byte[] buffer;
for(;;)
{
remoteEP = null;
buffer = server.Receive(ref remoteEP);
if (buffer != null && buffer.Length > 0)
{
Console.WriteLine("UDP: " + Encoding.ASCII.GetString(buffer));
}
}
}
catch (SocketException ex)
{
if(ex.ErrorCode != 10004) // unexpected
Console.WriteLine("UDPServerProc exception: " + ex);
}
catch (Exception ex)
{
Console.WriteLine("UDPServerProc exception: " + ex);
}
Console.WriteLine("UDP server thread finished");
}
private static void TCPServerProc(object arg)
{
Console.WriteLine("TCP server thread started");
try
{
TcpListener server = (TcpListener)arg;
byte[] buffer = new byte[2048];
int count;
server.Start();
for(;;)
{
TcpClient client = server.AcceptTcpClient();
using (var stream = client.GetStream())
{
while ((count = stream.Read(buffer, 0, buffer.Length)) != 0)
{
Console.WriteLine("TCP: " + Encoding.ASCII.GetString(buffer, 0, count));
}
}
client.Close();
}
}
catch (SocketException ex)
{
if (ex.ErrorCode != 10004) // unexpected
Console.WriteLine("TCPServerProc exception: " + ex);
}
catch (Exception ex)
{
Console.WriteLine("TCPServerProc exception: " + ex);
}
Console.WriteLine("TCP server thread finished");
}
}
}
客户:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace TCPUDPClient
{
class Program
{
static void Main(string[] args)
{
UdpClient udpClient = null;
TcpClient tcpClient = null;
NetworkStream tcpStream = null;
int port = 59567;
ConsoleKeyInfo key;
bool run = true;
byte[] buffer;
Console.WriteLine(string.Format("Starting TCP and UDP clients on port {0}...", port));
try
{
udpClient = new UdpClient();
udpClient.Connect(IPAddress.Loopback, port);
tcpClient = new TcpClient();
tcpClient.Connect(IPAddress.Loopback, port);
while(run)
{
Console.WriteLine("Press 'T' for TCP sending, 'U' for UDP sending or 'X' to exit.");
key = Console.ReadKey(true);
switch (key.Key)
{
case ConsoleKey.X:
run = false;
break;
case ConsoleKey.U:
buffer = Encoding.ASCII.GetBytes(DateTime.Now.ToString("HH:mm:ss.fff"));
udpClient.Send(buffer, buffer.Length);
break;
case ConsoleKey.T:
buffer = Encoding.ASCII.GetBytes(DateTime.Now.ToString("HH:mm:ss.fff"));
if (tcpStream == null)
tcpStream = tcpClient.GetStream();
tcpStream.Write(buffer, 0, buffer.Length);
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine("Main exception: " + ex);
}
finally
{
if(udpClient != null)
udpClient.Close();
if(tcpStream != null)
tcpStream.Close();
if(tcpClient != null)
tcpClient.Close();
}
Console.WriteLine("Press <ENTER> to exit.");
Console.ReadLine();
}
}
}
我将切入正题,我已经在这个问题上停留了几个小时了。大量 Google 和大量研究,但目前还没有直接的答案。
我有一个客户端和一个为 TCP 编码的服务器,它们运行良好,但是,我希望客户端也能够将 UDP 与服务器一起用于 none - 重要的数据包,例如播放器位置。
截至目前,这是我连接客户端的连接代码。
public void ConnectToServer(){
tcp_client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
tcp_client.Connect(server_ip, server_port);
tcp_stream = new NetworkStream(this.tcp_client);
this.udp_client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
this.udp_client.BeginConnect(IPAddress.Parse(server_ip), server_port,new AsyncCallback(udp_connected), null);
}
现在客户端不是我遇到的问题,因为当我使用 udp.Send(byteArray)
它似乎正在发送,因为它没有抛出任何异常,但服务器本身没有响应接收到的任何数据.
请注意这不是 100% copy/pasted 代码。更改以显示问题所在。
private Socket c;
private UdpClient udp;
private isRunning = true;
public Client(Socket c){
// This was accepted from TcpListener on Main Server Thread.
this.c = c;
this.networkStream = new NetworkStream(this.c);
udp = new UdpClient();
udp.Connect((IPEndPoint)c.RemoteEndPoint);
// Then starts 2 thread for listening, 1 for TCP and 1 for UDP.
}
private void handleUDPTraffic(){
IPEndPoint groupEP = (IPEndPoint)c.RemoteEndPoint;
while (isRunning){
try{
byte[] udp_received = udp.Receive(ref groupEP);
Console.WriteLine("Received UDP Packet Data: " + udp_received.Length);
}catch{
log.ERROR("UDP", "Couldn't Receive Data...");
}
}
}
您可以在同一端口上同时使用 TCP 和 UDP。另见:
Can TCP and UDP sockets use the same port?
下面的示例演示了您可以同时发送和接收 UDP 和 TCP 消息。
也许,您创建的用于侦听传入数据报的 UdpClient 就是问题所在。我建议像您的 TcpListener 一样创建一次。
服务器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TCPUDPServer
{
class Program
{
static void Main(string[] args)
{
TcpListener tcpServer = null;
UdpClient udpServer = null;
int port = 59567;
Console.WriteLine(string.Format("Starting TCP and UDP servers on port {0}...", port));
try
{
udpServer = new UdpClient(port);
tcpServer = new TcpListener(IPAddress.Any, port);
var udpThread = new Thread(new ParameterizedThreadStart(UDPServerProc));
udpThread.IsBackground = true;
udpThread.Name = "UDP server thread";
udpThread.Start(udpServer);
var tcpThread = new Thread(new ParameterizedThreadStart(TCPServerProc));
tcpThread.IsBackground = true;
tcpThread.Name = "TCP server thread";
tcpThread.Start(tcpServer);
Console.WriteLine("Press <ENTER> to stop the servers.");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Main exception: " + ex);
}
finally
{
if (udpServer != null)
udpServer.Close();
if (tcpServer != null)
tcpServer.Stop();
}
Console.WriteLine("Press <ENTER> to exit.");
Console.ReadLine();
}
private static void UDPServerProc(object arg)
{
Console.WriteLine("UDP server thread started");
try
{
UdpClient server = (UdpClient)arg;
IPEndPoint remoteEP;
byte[] buffer;
for(;;)
{
remoteEP = null;
buffer = server.Receive(ref remoteEP);
if (buffer != null && buffer.Length > 0)
{
Console.WriteLine("UDP: " + Encoding.ASCII.GetString(buffer));
}
}
}
catch (SocketException ex)
{
if(ex.ErrorCode != 10004) // unexpected
Console.WriteLine("UDPServerProc exception: " + ex);
}
catch (Exception ex)
{
Console.WriteLine("UDPServerProc exception: " + ex);
}
Console.WriteLine("UDP server thread finished");
}
private static void TCPServerProc(object arg)
{
Console.WriteLine("TCP server thread started");
try
{
TcpListener server = (TcpListener)arg;
byte[] buffer = new byte[2048];
int count;
server.Start();
for(;;)
{
TcpClient client = server.AcceptTcpClient();
using (var stream = client.GetStream())
{
while ((count = stream.Read(buffer, 0, buffer.Length)) != 0)
{
Console.WriteLine("TCP: " + Encoding.ASCII.GetString(buffer, 0, count));
}
}
client.Close();
}
}
catch (SocketException ex)
{
if (ex.ErrorCode != 10004) // unexpected
Console.WriteLine("TCPServerProc exception: " + ex);
}
catch (Exception ex)
{
Console.WriteLine("TCPServerProc exception: " + ex);
}
Console.WriteLine("TCP server thread finished");
}
}
}
客户:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace TCPUDPClient
{
class Program
{
static void Main(string[] args)
{
UdpClient udpClient = null;
TcpClient tcpClient = null;
NetworkStream tcpStream = null;
int port = 59567;
ConsoleKeyInfo key;
bool run = true;
byte[] buffer;
Console.WriteLine(string.Format("Starting TCP and UDP clients on port {0}...", port));
try
{
udpClient = new UdpClient();
udpClient.Connect(IPAddress.Loopback, port);
tcpClient = new TcpClient();
tcpClient.Connect(IPAddress.Loopback, port);
while(run)
{
Console.WriteLine("Press 'T' for TCP sending, 'U' for UDP sending or 'X' to exit.");
key = Console.ReadKey(true);
switch (key.Key)
{
case ConsoleKey.X:
run = false;
break;
case ConsoleKey.U:
buffer = Encoding.ASCII.GetBytes(DateTime.Now.ToString("HH:mm:ss.fff"));
udpClient.Send(buffer, buffer.Length);
break;
case ConsoleKey.T:
buffer = Encoding.ASCII.GetBytes(DateTime.Now.ToString("HH:mm:ss.fff"));
if (tcpStream == null)
tcpStream = tcpClient.GetStream();
tcpStream.Write(buffer, 0, buffer.Length);
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine("Main exception: " + ex);
}
finally
{
if(udpClient != null)
udpClient.Close();
if(tcpStream != null)
tcpStream.Close();
if(tcpClient != null)
tcpClient.Close();
}
Console.WriteLine("Press <ENTER> to exit.");
Console.ReadLine();
}
}
}