如何使用C中的socket编程在internet上连接两台计算机?
这是一个简单的客户端-服务器聊天程序。这段代码在连接到网络上的计算机上运行良好,如何修改它,使其能够通过Internet在计算机之间连接。在如何使用C中的socket编程在internet上连接两台计算机?,c,sockets,network-programming,C,Sockets,Network Programming,这是一个简单的客户端-服务器聊天程序。这段代码在连接到网络上的计算机上运行良好,如何修改它,使其能够通过Internet在计算机之间连接。在gethostbyname()中使用服务器的公共IP无效 //Client.c #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<netdb.h> #in
gethostbyname()
中使用服务器的公共IP无效
//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;
}
//Client.c
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
int clientSocket;/*客户端的套接字描述符*/
服务器地址中的结构sockaddr\u;
结构主机*ptrh;
字符消息[100];
收到字符[100];
int n=0;
clientSocket=socket(AF\u INET,SOCK\u STREAM,0);
memset((char*)&server_addr,0,sizeof(server_addr));
服务器地址sin家庭=AF网络;
服务器地址sin端口=htons(10000);
/*绑定(clientSocket,(struct sockaddr*)和服务器地址,sizeof(struct sockaddr))*/
ptrh=gethostbyname(“110.172.156.2”);
memcpy(&server\u addr.sin\u addr,ptrh->h\u addr,ptrh->h\u length);
if(-1==(connect(clientSocket,(struct sockaddr*)和server\u addr,sizeof(server\u addr)))
{printf(“\n服务器未就绪!!\n”);退出(1);}
而(1)
{
printf(“\n用户:-”);
//memset(消息“\0”,10);
获取(消息);
n=写入(客户端套接字、消息、strlen(消息)+1);
如果((strcmp(消息,“q”)==0)| |(strcmp(消息,“q”)==0))
{
printf(“错误的位置…插座关闭\n”);
关闭(clientSocket);
打破
}
//printf(“写入:\n”,n);
读取(clientSocket,received,sizeof(received));
如果((strcmp(已接收,“q”)==0)| |(strcmp(已接收,“q”)==0))
{
printf(“错误的位置…插座关闭\n”);
关闭(clientSocket);
打破
}
其他的
printf(“服务器:-%s\n”,已收到);
}
返回0;
}
//服务器.c
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
int serverSocket,已连接客户端,len;
客户端地址、服务器地址中的结构sockaddr\u;
结构主机*ptrh;
int n=0;
字符消息[100],收到[100];
serverSocket=socket(AF\u INET,SOCK\u STREAM,0);
memset((char*)&server_addr,0,sizeof(server_addr));
服务器地址sin家庭=AF网络;
服务器地址sin端口=htons(10000);
服务器地址sin地址s地址=htonl(INADDR\U ANY);
如果(绑定)服务器套接字,
(struct sockaddr*)和服务器地址,sizeof(服务器地址))=-1)
printf(“绑定失败\n”);
其他的
printf(“绑定成功:\n”,serverSocket);
而(1)
{
监听(serverSocket,5);
len=sizeof(结构sockaddr_in);
客户端\u已连接=接受(服务器套接字,
(struct sockaddr*)和client_addr和len);
如果(-1!=客户端已连接)
printf(“已接受连接:\n”,客户端已连接);
而(1)
{
n=读取(客户端已连接、已接收、sizeof(已接收));
如果((strcmp(已接收,“q”)==0)| |(strcmp(已接收,“q”)==0))
{
printf(“错误的位置…客户端的套接字已关闭\n”);
关闭(已连接客户端);
打破
}
否则{
printf(“\n用户:-%s”,已收到);}
printf(“\n服务器:-”);
//memset(消息“\0”,10);
获取(消息);
写入(客户端已连接,消息,大小(消息));
如果((strcmp(消息,“q”)==0)| |(strcmp(消息,“q”)==0))
{
printf(“错误的位置…客户端的套接字已关闭\n”);
关闭(已连接客户端);
打破
}
}
}
关闭(服务器套接字);printf(“\n服务器套接字已关闭!!\n”);
返回0;
}
根据您提供的信息,我认为不可能为您提出的问题提供解决方案。您已经说过,当两台计算机在同一个本地网络上时,您的代码可以工作,因此很明显,代码(是的,有问题)至少可以很好地从客户端连接到服务器
如果(正如所确定的那样)代码可以工作,那么客户机和服务器是在同一个网络上还是在不同的网络上并不重要,只要两个网络之间有路由、路径和连接。因此,如果客户机无法连接到服务器,则结论是缺少此路径。然而,路径丢失并不是我们可以为您解决的问题:可能是“我的‘Windows防火墙’正在阻止此应用程序”,可能是“我的ISP(或其他人的ISP)正在阻止此端口,可能是”其他人的ISP服务条款包含“无服务器”条款,他们通过阻止所有端口强制执行该条款,甚至可能是“我的ISP与另一个人的ISP发生冲突,不再向他们发送数据包”
然而,由于您已经费尽心思发布此代码,而我也费尽心思(a)阅读此代码,以及(b)编写响应,因此我决定在您的代码中添加一些关于我看到的问题的注释。请注意,这保证不是一个详尽的列表
在Client.c中:
- 您正在调用,并将第一个参数强制转换为
。char*
函数定义为将memset()
作为第一个参数。由于您已经#包括了void*
,所以范围内有一个正确的原型,因此您传递给它的任何内容都将自动转换为
。因此,演员阵容既不正确也毫无意义void*
- 您正在调用
,而您传递的字符串是IPv4地址gethostbyname()
- POSIX.1-2004中弃用了
和gethostbyname()
函数,并将其从POSIX.1-2008中排除。它们被(和)替换,请参阅以了解更多信息gethostbyaddr()
- 根据POSIX.1-2004,“传递数字地址字符串时gethostbyname()的行为未指定”。
函数需要传递一个实际的主机名,对于IP地址,有gethostbyname()
。(当然,现在也可以使用gethostbyaddr()
)getaddrinfo()
- 您正在使用
函数。C99中弃用了get()
函数,在POSIX.1-2008中标记为已过时,并从C11中排除,因为它基本上是unsafgets()