c# - c#网络客户端从TCP上的同一端口发送和接收数据
问题描述
我的任务是编写一个多线程客户端(有一个用于发送数据的线程和一个用于接收数据的不同线程)。出于某种原因,客户(为我的工作买单的人)坚持我使用相同的端口来发送(到服务器)和接收数据(从服务器)。据我所知,这不应该是不可能的,所以这就是我在这里的原因,看看我是否错了。
发送线程:
public void Send_msg()
{
while (!GlobalVar.is_conn) { }
try
{
socket = new Socket(AddressFamily.InterNetwork, GlobalVar._isTcp ? SocketType.Stream : SocketType.Dgram, GlobalVar._isTcp ? ProtocolType.Tcp : ProtocolType.Udp);
IPEndPoint end_point = new IPEndPoint(Mul_ip, Mul_port);
if (GlobalVar._isTcp)
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseUnicastPort, true);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, true);
}
else
{
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(Mul_ip, IPAddress.Any));
}
socket.Bind(new IPEndPoint(IPAddress.Any,Mul_port));
socket.Connect(end_point);
GlobalVar.socketWasConfiged = true;
while (!_shouldStop)
{
while (!Send_msg_queue.IsEmpty)
{ //while there are more messages to send
Send_msg_queue.TryDequeue(out CM_msg send_msg);
byte[] send_buff = Encoder(send_msg);
try
{
socket.Send(send_buff, SocketFlags.None);
GlobalVar.Is_Wd_Rec = false;
}
catch (Exception e)
{
MessageBox.Show("Error while trying to send a message: " + e.Message, "Error");
}
}
}
}
catch(Exception e)
{
MessageBox.Show("Error while trying to send a message: " + e.Message, "Error");
}
finally
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
socket.Close();
}
可以看出,我打开一个套接字,通过 setSocketOption 更改其选项,然后绑定并连接到服务器,然后线程对一些队列进行采样并在发送消息时发送消息。同时应该接收消息的线程这样做:
public void Receive_msg()
{
while (!GlobalVar.is_conn) { }
try
{
while (!GlobalVar.socketWasConfiged) { }
byte[] rec_buff = new byte[size];
socket = new Socket(AddressFamily.InterNetwork,GlobalVar._isTcp? SocketType.Stream : SocketType.Dgram,GlobalVar._isTcp? ProtocolType.Tcp : ProtocolType.Udp);
IPEndPoint end_point = new IPEndPoint(IPAddress.Any, Mul_port);
if(GlobalVar._isTcp)
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseUnicastPort, true);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, true);
}
else
{
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(Mul_ip, IPAddress.Any));
}
socket.Bind(end_point);
socket.Connect(new IPEndPoint(Mul_ip, Mul_port));
while (!_shouldStop)
{
size_rec = socket.Receive(rec_buff);
GlobalVar.Counter_auto = GlobalVar.Counter_auto + 1;
Receive_msg_queue.Enqueue(Decoder(rec_buff));
// if a message was recieved than there is a connection to the unit, so we make Is_Wd_Rec true
GlobalVar.Is_Wd_Rec = true;
}
}
catch (Exception e)
{
MessageBox.Show("An error occur while trying to receive a message: " + e.Message);
}
finally
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
socket.Close();
}
}
可以看出,监听线程一直等到某个 globalVar 为真(所以我们不会得到并发的套接字绑定),然后它初始化套接字并尝试绑定/连接到服务器。一旦它尝试连接,我就会得到一个异常,它无法连接到已经连接的套接字。
有什么办法可以解决这个问题吗?还是我应该告诉客户端服务器应该写入不同的端口?
解决方案
推荐阅读
- sql - 由于排序规则冲突,无法执行 varchar 值到 varchar 的隐式转换
- go - 通过堡垒主机 SSH
- javascript - 生成与 IPFS-Desktop CID 匹配的 CID 的无节点方式
- r - 识别 R 中所有权的变化
- python - 使用 matplotlib 从 3 列文件中绘制极坐标热图
- google-bigquery - 将表中的数组单元格转换为另一个表中的行
- flutter - 在 runapp 上使用两个更改通知器 Flutter
- java - 如何使用 Glide 从 Firebase 存储中显示图像
- jsx - 在 After Effects 法语版本上使用 findMenuCommandId('string with accent') 不起作用
- javascript - HighStock 中 xAxis 的 softMin/softMax 未设置?