简体   繁体   English

从中间有服务器的另一个客户端向特定客户端发送数据[C#]

[英]Send data to specific client from another client with a server in middle[C#]

I have searched everywhere but couldn't find as they are all answering to send message to all clients.我到处搜索但找不到,因为他们都在回答向所有客户发送消息。 What I want to achieve is multiple clients request to server to request data from another client and other client sends data to server telling it that data is for requesting client and so.我想要实现的是多个客户端请求服务器从另一个客户端请求数据,而其他客户端向服务器发送数据,告诉它数据是用于请求客户端的,等等。 I don't know how to achieve this.我不知道如何实现这一目标。 I'm new to this.我对此很陌生。

What I want to achieve:我想要达到的目标:

在此处输入图像描述

I have tried with Data sending client to listen and requesting client to connect to it and transfer data.我已经尝试使用数据发送客户端来监听并请求客户端连接到它并传输数据。 I have achieved this on local.network but to make it work online it needs port forwarding and my user will be a lot of different people so port forwarding is not possible for every user.我已经在 local.network 上实现了这一点,但要让它在线工作,它需要端口转发,而且我的用户会有很多不同的人,所以端口转发对每个用户来说都是不可能的。 So I can rent a server which will act as a center of transfer.所以我可以租用一台服务器作为传输中心。 I programmed a test server in console which will listen to a server IP:port X and accept new clients and their data on port X and forward it to server IP:port Y but what this does is send data to all clients on port Y. I cannot send it to clients public ip address directly for obvious reasons.我在控制台中编写了一个测试服务器,它将侦听服务器 IP:port X 并接受新客户端及其在端口 X 上的数据并将其转发到服务器 IP:port Y 但这样做是将数据发送到端口 Y 上的所有客户端。由于显而易见的原因,我不能直接将它发送给客户公共 ip 地址。 I understand that all the requesting clients are connected to port Y but I cannot create and assign new ports to all the clients interacting.我知道所有发出请求的客户端都连接到端口 Y,但我无法为所有交互的客户端创建和分配新端口。 So I want a way to determine how to request and receive the data without the need of assigning or creating new ports to different clients on same server.所以我想要一种方法来确定如何请求和接收数据,而无需为同一服务器上的不同客户端分配或创建新端口。

What I have tried:我试过的:

Server code服务器代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Test___server
{
    class server
    {
        public static string serverIP = "192.168.0.102";
        static void Main(string[] args)
        {
            Thread listenSendingThread = new Thread(listenSending);
            listenSendingThread.IsBackground = true;
            listenSendingThread.Start();
            Thread listenReceivingThread = new Thread(listenReceiving);
            listenReceivingThread.IsBackground = true;
            listenReceivingThread.Start();
            Console.ReadKey();
        }

        public static List<TcpClient> listSending = new List<TcpClient>();
        public static List<TcpClient> listReceiving = new List<TcpClient>();
        public static TcpClient clientSending = null;
        private static void listenSending()
        {
            TcpListener listenerSending = new TcpListener(IPAddress.Parse(serverIP), 5319);
            listenerSending.Start();
            Console.WriteLine("Server listening to " + serverIP + ":5319");
            while(true)
            {
                clientSending = listenerSending.AcceptTcpClient();
                listSending.Add(clientSending);
                Console.WriteLine("Sender connection received from " + clientSending.Client.RemoteEndPoint);
            }
        }
        private static void send()
        {
            StreamWriter sw = new StreamWriter(clientSending.GetStream());
            sw.WriteLine(message);
            sw.Flush();
            Console.WriteLine("Message sent!");
        }

        public static string message = string.Empty;
            
        private static void listenReceiving()
        {
            TcpListener listener = new TcpListener(IPAddress.Parse(serverIP), 0045);
            listener.Start();
            Console.WriteLine("Server listening to " + serverIP + ":0045");
            while (true)
            {
                TcpClient client = listener.AcceptTcpClient();
                listReceiving.Add(client);
                Console.WriteLine("Receiver connection received from " + client.Client.RemoteEndPoint);
                StreamReader sr = new StreamReader(client.GetStream());
                message = sr.ReadLine();
                send();
            }
        }
    }
}

Requesting client code请求客户端代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test____admin
{
    class admin
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Begin");
            string serverIP = "192.168.0.102";
            System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
            clientSocket.Connect(serverIP,  );
            Console.WriteLine("Connected");
            while (true)
            {
                Console.WriteLine("Reading");
                StreamReader sr = new StreamReader(clientSocket.GetStream());
                Console.WriteLine("Message: " + sr.ReadLine());
            }
        }
    }
}

Request satisfying client code请求满足客户端代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Test___client
{
    class client
    {
        public static string serverIP = "192.168.0.102";
        static void Main(string[] args)
        {
            clientConnect();
        }

        private static void clientConnect()
        {
            try
            {
                TcpClient client = new TcpClient(serverIP, 0045);
                StreamWriter sw = new StreamWriter(client.GetStream());
                sw.WriteLine("Karan!");
                sw.Flush();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

You are using a very low-level API, and doing it the right way is challenging.您正在使用一个非常低级的 API,并且以正确的方式进行操作具有挑战性。 Instead, try YARP as a reverse proxy.相反,尝试将 YARP作为反向代理。 The requesting client should notify the reverse proxy about the desired destination client.请求客户端应通知反向代理所需的目标客户端。 One option is sending the destination client name in the request header .一种选择是在请求中发送目标客户端名称 header You will also need to split a single server request into multiple client requests, then merge their responses into a single one.您还需要将单个服务器请求拆分为多个客户端请求,然后将它们的响应合并为一个。 You can achieve it by implementing Transphorms .您可以通过实施Transphorms来实现它。

I'm not sure this approach applies to your situation because clients should implement server API using REST, Grpc or any other supported technology.我不确定这种方法是否适用于您的情况,因为客户端应该使用 REST、Grpc 或任何其他支持的技术来实现服务器 API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM