Comment connecter deux ordinateurs via internet en utilisant la programmation socket en C?
C'est simple Client-Serveur programme de chat.Ce code fonctionne bien sur les ordinateurs connectés sur le Réseau, comment le modifier pour qu'elle puisse se connecter entre ordinateurs sur Internet. Utilisant l'adresse IP Publique du serveur dans gethostbyname()
ne fonctionne pas.
//Client.c
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
int clientSocket; /* Socket Decriptor for Client */
struct sockaddr_in server_addr;
struct hostent *ptrh;
char message[100];
char received[100];
int n = 0;
clientSocket=socket(AF_INET, SOCK_STREAM, 0);
memset((char*)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(10000);
/* bind(clientSocket, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)); */
ptrh=gethostbyname("110.172.156.2");
memcpy(&server_addr.sin_addr,ptrh->h_addr,ptrh->h_length);
if( -1 == (connect(clientSocket, (struct sockaddr*)&server_addr, sizeof(server_addr))))
{ printf("\nServer Not Ready !!\n"); exit(1); }
while(1)
{
printf("\nUser:-");
//memset(message, '\0', 10);
gets(message);
n = write(clientSocket, message, strlen(message)+1);
if( (strcmp(message,"q") == 0 ) || (strcmp(message,"Q") == 0 ))
{
printf("Wrong place...Socket Closed\n");
close(clientSocket);
break;
}
//printf("Write:<%u>\n", n);
read(clientSocket, received, sizeof(received));
if( (strcmp(received,"q") == 0 ) || (strcmp(received,"Q") == 0 ))
{
printf("Wrong place...Socket Closed\n");
close(clientSocket);
break;
}
else
printf("Server:- %s\n", received);
}
return 0;
}
//Server.c
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<netdb.h>
int main(void)
{
int serverSocket,client_connected,len;
struct sockaddr_in client_addr,server_addr;
struct hostent *ptrh;
int n=0;
char message[100],received[100];
serverSocket=socket(AF_INET, SOCK_STREAM, 0);
memset((char*)&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(10000);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(serverSocket,
(struct sockaddr*)&server_addr,sizeof(server_addr)) == -1)
printf("Bind Failure\n");
else
printf("Bind Success:<%u>\n", serverSocket);
while(1)
{
listen(serverSocket,5);
len=sizeof(struct sockaddr_in);
client_connected=accept(serverSocket,
(struct sockaddr*)&client_addr,&len);
if (-1 != client_connected)
printf("Connection accepted:<%u>\n", client_connected);
while(1)
{
n = read(client_connected, received, sizeof(received));
if( (strcmp(received,"q") == 0 ) || (strcmp(received,"Q") == 0 ))
{
printf("Wrong place...Socket Closed of Client\n");
close(client_connected);
break;
}
else{
printf("\nUser:-%s", received);}
printf("\nServer:-");
// memset(message, '\0', 10);
gets(message);
write(client_connected, message, sizeof(message));
if( (strcmp(message,"q") == 0 ) || (strcmp(message,"Q") == 0 ))
{
printf("Wrong place...Socket Closed of Client\n");
close(client_connected);
break;
}
}
}
close(serverSocket); printf("\nServer Socket Closed !!\n");
return 0;
}
- avez-vous configuré la redirection de port sur le routeur, vous voulez vous connecter?
- Soit vous derrière des routeurs NAT? Avez-vous transmis les ports appropriés?
- - Vous sûr que ce n'est pas un problème de pare-feu?
- Outre les possibles problèmes de pare-feu, lorsqu'un appel système comme
connect
échoue, puis de vérifiererrno
(et l'impression de sortir avec, par exemple,perror
) est généralement une bonne idée.
Vous devez vous connecter pour publier un commentaire.
Sur la base des informations que vous avez donné, je ne pense pas qu'il est possible de fournir une solution à la question que vous posez cette question. Vous avez déclaré que votre code fonctionne lorsque les deux ordinateurs sont sur le même réseau local, donc clairement le code (qui, oui, a des problèmes) travaille au moins assez bien pour vous connecter à partir du serveur vers le client.
Si (comme c'est établi, le code fonctionne, alors il ne devrait pas d'importance si le client et le serveur sont sur le même réseau ou des réseaux distincts, tant qu'il y a une route, un chemin, une connexion entre les deux réseaux. Par conséquent, si le client ne peut pas se connecter au serveur, la conclusion est que ce chemin est manquant. Le chemin étant manquant, cependant, n'est pas un problème que nous pouvons résoudre pour vous: Il est peut-être "mon" Pare-feu Windows "est le blocage de cette application", il pourrait être mon FAI (ou de l'autre gars FAI) bloque ce port, il pourrait être "de L'autre gars termes de service auprès de son FAI comprend un "pas de serveurs" clause dont ils les appliquent en bloquant tous ports", il pourrait même être "de mon fournisseur d'accès est en froid avec les autres gars du fournisseur de services internet et de ne pas acheminer les paquets à eux".
Cependant, puisque vous avez pris la peine de poster ce code, et je suis allé à la peine de (un) de le lire, et (b) écrire une réponse, j'ai décidé d'inclure des commentaires sur les problèmes que je vois dans votre code. Notez que ceci est garanti pas être une liste exhaustive.
Au Client.c:
memset()
, et le casting du premier argument dechar *
. Lememset()
fonction est définie pour prendre unvoid *
comme premier argument. Depuis que vous avez incluses<string.h>
vous avez un bon prototype de la portée, de sorte que vous passer à elle sera convertie en unevoid *
automatiquement. Le casting est donc à la fois incorrect et inutile.gethostbyname()
, et la chaîne que vous êtes en passant est une adresse IPv4.gethostbyname()
etgethostbyaddr()
fonctions ont été désapprouvées dans POSIX.1-2004 et ont été exclus de POSIX.1-2008 date. Ils sont remplacés pargetaddrinfo()
(etgetnameinfo()
), et je vous renvoie à L'article 5.1 deBeej Guide de Programmation du Réseau
pour de plus amples informations.gethostbyname()
fonction s'attend à être passé d'un nom d'hôte, les adresses IP, il n'y agethostbyaddr()
. (Ougetaddrinfo()
maintenant, bien sûr).gets()
fonction. Legets()
fonction a été dépréciée en C99, marqué comme Obsolète dans POSIX.1-2008 date et l'exclusion du C11, parce qu'il est fondamentalement dangereux en raison de n'avoir aucun moyen de limiter la taille de l'image. Généralement alternative recommandée estfgets()
, noter que, contrairement àgets()
, lefgets()
fonction ne jetez pas de l'\n
caractère.Dans Le Serveur.c:
memset()
àchar *
, qui est toujours inutile et mal,gets()
fonction, qui reste intrinsèquement problématique,write(client_connected, message, sizeof(message));
. Chaque réponse du serveur sera le plein de 100 octets de long, avec des déchets d'octets écrits après la chaîne de réponse. Utilisationstrlen(message)+1
à la place.À la fois:
strlen(message)
.Bien après mes recherches, j'ai trouvé cette réponse. Si vous souhaitez connecter des Périphériques sur Internet, vous devez disposer d'un Serveur ayant une Adresse IP unique, par exemple, vous pourriez acheter un en ligne. Lorsque vous essayez de créer un périphérique de votre réseau domestique en tant que Serveur, vous devez fournir l'Adresse IP Globale et depuis le FAI vous fournit avec une seule IP Publique partagée par un grand nombre d'appareils sur le Réseau à l'aide d'un routeur, vous ne pouvez pas créer un ServerSocket sur un réseau Domestique partagée par de nombreux Appareils
Vous ne pouvez pas vous connecter à un appareil uniquement par le mondial de la propriété intellectuelle, mais si vous ouvrez un port, le port de l'avant, uniquement pour le serveur, puis le support peut être faite.