Connecter deux sockets client
Disons que Java a deux types de sockets:
- serveur de sockets "ServerSocket"
- sockets client ou tout simplement de "Socket"
Imaginer la situation de deux processus:
X = Client
Y = Serveur
Le processus de serveur de Y : a "ServerSocket", qui est à l'écoute sur un port TCP
Le processus client X : envoie une demande de connexion par le biais d'un "Socket" pour Y.
Y: Alors la accept()
méthode renvoie un nouveau client de type "Socket",
lorsque cela se produit, les deux Douilles d'obtenir "interconnectés",
Donc: la prise en processus client est connecté avec le support dans le processus serveur.
Ensuite: la lecture/écriture par le biais de prise X, c'est comme la lecture/écriture par le biais de prise Y.
Maintenant, deux Client Sockets obtenir interconnectés!!
Mais...
Que faire si je créer les deux sockets Client dans le même processus,
et je veux les faire "interconnectés" ?
... même possible?
Disons comment avoir deux socket client obtenir reliés entre eux sans l'aide d'un intermédiaire ServerSocket?
Je l'ai résolu par la création de deux Threads en continu, la lecture de l'Un et de l'écriture B,
et d'autres pour la lecture B et en écriture d'Un...
Mais je pense pourrait être une meilleure façon...
(Ceux du monde de consommation d'énergie threads ne sont pas nécessaires avec l'approche client-serveur)
De l'aide ou des conseils seraient appréciés!! Grâce
Edit:
Exemple d'application: "Un existant de l'application serveur peut être converti en un seul client",
Par exemple, le serveur VNC, un socket client se connecte au serveur VNC, et d'autres client socket est créée (pour se connecter à un milieu serveur), alors l'application relie les deux client résultant le serveur VNC est un client demande! Et puis, pas d'IP publique est nécessaire.
VNCServer---MyApp---> |moyen| serveur <---l'Utilisateur
- merci pour les commentaires, j'ai nettoyer un peu!, et éviter les bouchons. Pour être un mistakable sujet, j'ai essayé de l'expliquer lentement, merci
- Corrigez-moi si je me trompe, mais voici ce que j'ai compris: vous avez MyApp en cours d'exécution sur un serveur, VNCServer sur l'autre, et middleServer sur la troisième serveur. L'utilisateur se connecte à moyen serveur (qui je pense a une IP publique). Vous souhaitez vous connecter à VNCServer du moyen-serveur, mais votre VNCServer est à l'intérieur de certaines intranet et du moyen-serveur est à l'extérieur de ce réseau. Donc, vous voulez combler les connexions. Pour faire ce que vous avez écrit myApp (qui est à l'intérieur de l'intranet) ouvre une connexion à moyen-serveur, puis à VNCServer et vous souhaitez transmettre des données à partir du milieu du serveur de VNCServer. Est-ce à approcher?
- Eche, merci pour tout nettoyer et de fournir plus d'infos! Enlevé mon bas-vote.
- Oui qui viennent fermer, (VNCServer un MyApp peut-être même dans la même machine), et oui, le VNCServer pourrait être à l'intérieur d'un intranet, et j'pont les connexions, j'ai deux "MyApp" en cours d'exécution, l'Un dans l'intranet de interconect VNCServer avec le moyen-serveur (disons un clientsocket-à-clientsocket plug) et une au milieu serveur pour recréer un serveur (disons un serversocket-à-serversocket plug), J'ai même appelé les "adaptateurs" parce que cela me rappelle la femelle-femelle, mâle-mâle audio ou tout-adaptateurs de prise =)
- Quelqu'un peut seulement vous aider à optimiser le code, si vous le poster en premier.
- Oui! Je pense que je l'ai eu! Je pense que je sais ce que vous voulez. Tout comme TeamViewer. Ils ont un serveur qui tient qui est en ligne. Ce serveur a une IP publique statique où tous les clients peuvent se connecter. Donc, cela signifie que le "VNCServer" n'est pas vraiment un gros serveur de la machine. C'est aussi un client pour le réseau, mais il a un ServerSocket en cours d'exécution. Ainsi, le VNCServer peut dire que le serveur principal où il est (IP publique).
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, ne l'appelez pas accepté client (côté serveur) son support un
Client Socket
. C'est très déroutant.Ce qui est impossible. Vous avez toujours à faire côté serveur, ce qui peut accepter des clients. Maintenant, la question est: de quel côté de la connexion doit être le côté serveur?
Choses que vous devez penser, par la présente décision:
Je ne vois pas ce que vous voulez faire avec ce troisième serveur. Peut-être la tenue de la VNCServer IP publique?
*Elister* a écrit, vous voulez faire un pont entre le client et le VNCServer. Je ne vois pas l'avantage.
Pourquoi ne pas faire immédiatement une connexion à la VNCServer?
Mais si vous le voulez vraiment, vous pouvez faire ce genre de situation:
Et c'est à quoi il ressemble sans le troisième serveur (Ce que je vous recommande):
EDIT:
Je crois que j'ai maintenant:
Nous avons de visualiser votre situation comme ceci:
(1)
La VNCServer se connecte au serveur principal. De la sorte, alors le serveur principal a obtenu le VNCServer son adresse IP.(2)
Le client se connecte au serveur principal.(3)
Maintenant le serveur principal sait où le serveur et le client sont. Puis il envoie au client sur le serveur. Ensuite, le client va se connecter à l'IP, il a reçu du serveur principal. C'est bien sûr l'adresse IP du VNCServer.(5)
La VNCServer est en cours d'exécution du serveur est d'accepter le client.Maintenant de partage de bureau peut commencer.
Je pense que c'est le plus recommander situation que vous pouvez avoir.
Bien sûr écrit en Java est à vous.
Pourquoi auriez-vous besoin de faire cela?
Si vous voulez avoir un "peer-to-peer" type de système, alors vous avez juste à chaque client d'exécuter à la fois un client et un serveur de socket - le socket serveur pour accepter les connexions provenant d'autres clients et le socket client pour établir des connexions à d'autres.
ETA: Ce n'était pas tout à fait clair ce que vous demandez dans la question d'origine, mais depuis votre montage, il semble que vous cherchez à créer une sorte de serveur proxy.
Dans votre exemple, votre application serait de créer deux sockets client, une connexion à la VNCServer et l'autre de la connexion au "centre serveur". Le "centre serveur" aurait alors deux sockets serveur (un pour votre application pour vous connecter à et une pour l'utilisateur de se connecter. En interne, il aurait alors besoin de savoir comment faire correspondre ces prises et navette de données entre les deux.
Le ServerSocket vous permet d'écouter les connexions sur un port particulier. Lorsqu'un socket serveur accepte la connexion, il donne naissance à un autre thread, et déplace la connexion à un autre port, de sorte que le port d'origine peut toujours écouter les connexions supplémentaires.
Le client initie la connexion sur le port connus. Ensuite, généralement, le client devra envoyer une demande, et le serveur va répondre. Cette fonction permet de répéter jusqu'à ce que la communication est terminée. C'est la simple approche client/serveur que le site utilise des.
Si vous n'avez pas besoin de ce mécanisme, et les demandes peuvent provenir soit d'une prise à tout moment, la mise en œuvre, le lecteur et l'écrivain threads de la façon dont vous avez semble le plus approprié.
En interne, ils utilisent toujours attendre mécanismes, de sorte que vous ne devriez pas voir beaucoup d'utilisation de l'UC pendant qu'ils attendent pour les données arrivent.
Je pense que vous avez encore besoin d'une fin pour être un serveur de socket parce que je ne pense pas que c'est possible d'avoir un socket client d'accepter une connexion. ClientSocket implique TCP, ce qui nécessite une connexion. Si vous avez utilisé DatagramSocket, ce qui implique UDP, vous pourriez avoir de client à client de communication, sans connexion.
Êtes-vous essayer de créé un moqué de socket ? Si donc, en se moquant des deux côtés de la pipe peut être un peu plus compliqué que nécessaire.
D'autre part, si vous souhaitez simplement créer un canal de données entre deux threads, vous pouvez utiliser PipedInputStream et PipedOutputStream.
Toutefois, sans plus d'informations à propos de ce que vous essayez d'accomplir, je ne peux pas vous dire si l'un de ces choix est un bon choix ou si quelque chose d'autre serait mieux.
Un
socket
(en termes de réseautage) se compose de 2 points de terminaison (le client et Le serveur d'application) et 2streams
. Le flux de sortie du client est le flux d'entrée du serveur et vice-versa.Maintenant, essayez d'imaginer ce qui se passe si un thread écrit un grand nombre de données en un flux alors que personne ne lit... Il y a des tampons, c'est vrai, mais ils ne sont pas illimitées, et ils peuvent varier en taille. À la fin de votre thread d'écriture, le succès à la limite de la zone tampon et bloquera jusqu'à ce que quelqu'un libère la mémoire tampon.
Cela dit, vous devriez être conscient que cela aura besoin d'au moins deux threads différents par Flux: celui qui écrit et celui qui lit les écrits octets.
Si votre protocole de requête-réponse, de style, vous pourriez rester avec 2 threads par socket, mais pas moins.
Vous pouvez essayer de remplacer le réseau de votre application. Il suffit de créer une interface abstraite où vous pouvez masquer l'ensemble du réseau, comme:
Cette façon, vous pouvez facilement supprimer l'ensemble du réseau (y compris l'en- & décodage de vos objets, etc) et de minimiser le filetage.
Si vous voulez que les données binaires, vous pouvez utiliser des tubes à la place ou mettre en place votre propre flux pour empêcher le filetage.
L'entreprise ou de la logique de traitement ne devraient pas connaître les sockets, les ruisseaux sont de bas niveau assez et peut-être de trop.
Mais de toute façon: le Filetage n'est pas mauvais, tant que vous n'en abusez pas.
Je comprends ce que vous êtes après, j'ai eu à résoudre le même problème dans les situations où le serveur est derrière un camouflage de pare-feu avec une IP dynamique. J'ai utilisé une petite librement disponible programme, javaProxy pour fournir une solution. Il rend le serveur apparaître comme un socket client - en interne, il est encore un serveur, mais javaProxy fournit transfert de programme - Mon Application dans l'exemple - qui crée des connexions client "à partir de" le serveur. Il fournit également le proxy dans le milieu (Milieu du Serveur, dans l'exemple) pour rejoindre les deux extrémités de la socket client transmis par le serveur, et le client socket du client essaie de se connecter au serveur.
Le Moyen Serveur est hébergé à l'extérieur du pare-feu sur un IP connue. (Même si on peut faire semblant de le faire sans les sockets serveur, chaque connexion doit impliquer un client et un serveur de fin et nous nous assurons donc que le Moyen Serveur est sur un réseau IP que les clients peuvent les atteindre.) Dans mon cas, j'ai simplement utilisé un simple fournisseur d'hébergement permettez-moi de lancer un java à partir de la coquille.
Avec cette configuration, j'ai pu fournir l'accès au bureau à distance et d'autres services de courir derrière un pare-feu NAT avec une adresse IP dynamique, avec un accès à partir de mon ordinateur à la maison qui était aussi derrière un NAT avec une adresse IP dynamique. La seule adresse IP que j'ai besoin de savoir est l'adresse IP du Moyen Serveur.
Comme le filetage, le javaproxy bibliothèque est presque certainement mis en œuvre en utilisant des fils de la pompe de données entre le client sockets, mais ils ne consomment pas de ressources CPU (ou de puissance) alors qu'ils sont de blocage d'attente pour les I/O. Lorsque java 7 est publié avec le soutien de I/O asynchrone puis un thread par client socket paire ne sera pas nécessaire, mais c'est plus sur les performances et éviter de limite sur le nombre maximum de threads (pile), plutôt que de la consommation d'énergie.
À la mise en œuvre de ce vous-même avec deux sockets client dans le même processus nécessite l'utilisation de threads tant que java est dépendant de blocage I/O. Le modèle est de tirer à partir de la lecture de la fin et de pousser à l'écriture, à la fin, si un thread est nécessaire pour tirer à partir de la lecture de la fin. (Si nous l'avait poussée à partir de la lecture de la fin, j'.e asynchornous I/O, puis un thread dédié par socket paire ne sera pas nécessaire.)
Pourquoi avons-nous besoin d'un moyen de serveur? Si vous voulez juste pour exposer VNCServer. Pourquoi ne pas essayer une architecture comme suit
Dans ce cas MyApp agit à la fois comme un client (pour VNCServer) et un serveur(pour l'Utilisateur). Ainsi, vous aurez à mettre en œuvre à la fois le client et le serveur de sockets dans MyApp et transmet les données.
Edit: Pour communiquer avec VNCServer, MyApp besoins de connaître l'adresse IP de l'VNCServer. L'utilisateur ne seront communiquer avec MyApp et a seulement besoin de savoir MyApp l'Adresse IP. L'utilisateur n'a pas besoin de VNCServer l'adresse ip.
En C, vous pouvez appeler par socketpair(2) pour obtenir une paire de sockets connectées, mais je ne suis pas sûr si java est intégré dans la façon de faire la même chose.
En règle générale, un client TCP socket a deux extrémités (locale et “à distance”) et un serveur de socket TCP a une fin (car il est en attente pour un client de se connecter). Lorsqu'un client se connecte au serveur, le serveur en interne génère un client socket pour former connecté paire de sockets client qui représentent le canal de communication; c'est une paire parce que chaque prise de vues de la chaîne à partir d'une extrémité. C'est de cette Façon TCP Fonctionne (à haut niveau).
Vous ne pouvez pas avoir deux sockets client se connecter les uns aux autres dans TCP, comme le faible niveau de protocole de connexion ne fonctionne pas de cette façon. (Vous pouvez avoir un couple de prises créé de cette façon dans Unix, mais il n'est pas exposé en Java, et ils ne sont pas les sockets TCP.) Ce que vous peut faire est de fermer la socket du serveur une fois que vous avez accepté une connexion; pour les cas simples, qui pourrait être assez bon.
Les sockets UDP sont différents, bien sûr, mais ils travaillent avec des datagrammes et non de flux. C'est un modèle très différent de la communication.
Si vous voulez un
peer-to-peer
de connexion vous pouvez envisager d'utiliserUDP
.UDP
peut recevoir de quoi que ce soit sans l'établissement d'une connexion abord, vous aurez toujours besoin d'un serveur pour dire aux clients qu'ils sont de la réception de données à partir bien que.Espère que cela a aidé.
Le classique Java approche de connexion à base de socket de communication est de mettre en place un ServerSocket sur une IP et le port et sur le bloc, c'est accepter l'appel, qui (à la suite d'une tentative de connexion réussie) retourne une nouvelle Socket avec une mise en œuvre déterminée de port (différente de la ServerSocket's de port). Généralement, le retour de socket est transmis à un gestionnaire de mise en œuvre Praticable. Les gestionnaires sont temporairement associée à un lien particulier. Les gestionnaires peuvent être réutilisés et sont associés à un thread particulier en général pour la durée de vie de la connexion. Le blocage de la nature de classique Java socket IO rend la connexion de deux sockets servi par le même thread très difficile.
Toutefois, il est possible, et pas rare, à la fois d'entrée et de sortie des flux d'un socket sur le même thread et le soutien d'une seule connexion à la fois permet à la Praticable exigence d'être abandonné, c'est à dire pas de thread supplémentaire est nécessaire pour le gestionnaire et le ServerSocket accepter appel est reportée jusqu'à ce que la connexion en cours est fermé.
En fait, si vous utilisez NIO, vous pouvez facilement gérer plusieurs connexions simultanément sur le même thread à l'aide du Sélecteur mécanisme. C'est l'une des caractéristiques les plus importantes de NIO, non-blocage I/O à découpler les fils de connexions (permettant à un grand nombre de connexions à être manipulés par de petits pools de threads).
Autant que la topologie de votre système, je suis désolé, je ne suis pas encore clair ce que vous êtes après, mais ça sonne comme un travail pour un NAT service ou une sorte de proxy combler l'adresse IP publique à l'adresse IP privée.