linux socket编程,TCP,服务端和客户端可以本地通信了,分别放到两台主机上就连接不上了

雷格 2012-11-19 08:21:00
写了一个Socket小程序。在自己机子上测试是可以的。可是两台机子就连不通了。因为我用的是windows系统,所以实在虚拟机中编写并测试的。在一台虚拟机上可以相互通信。分别放到两台虚拟机上就连接不上了。服务端一直处于等待连接状态,客户端一值处于尝试连接中。两台主机的防火墙都关闭了。

下面我贴上代码,代码有点长,不过关键代码部分并不长。
Serever.c

#include "ImmediaCommunicate.h"

int main(int argc,char *argv[])
{
int sockfd,newsockfd;
struct sockaddr_in server_addr; /*define sever's sock address*/
struct sockaddr_in client_addr;
int sin_size,portnumber;
char buf[MAXSIZE];
MSG *pmsg = NULL;
pthread_t tidsend,tidrecv;

if(argc != 2)
{
fprintf(stderr,"%s paramete error!try again with port num\a\n",argv[0]);
exit(1);
}

if((portnumber = atoi(argv[1]))<0)
{
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);
exit(1);
}
/*socket...*/
if((sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)
{
fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
exit(1);
}
/*binging...*/
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(portnumber);
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr)) == -1)
{
fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
exit(1);
}

/*listening...*/
if(listen(sockfd,5) == -1)
{
fprintf(stderr,"listen error:%s\n\a",strerror(errno));
exit(1);
}
while(1)
{
printf("waiting for connect from a client...\n");
sin_size = sizeof(struct sockaddr_in);
if((newsockfd = accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size)) == -1)
{
fprintf(stderr,"accept error:%s\n\a",strerror(errno));
exit(1);
}
printf("Server get a connection from %s\n",inet_ntoa(client_addr.sin_addr));
pmsg =(MSG*)malloc(sizeof(MSG));
pmsg->sockfd = newsockfd;
pmsg->ipstr =(char*)inet_ntoa(client_addr.sin_addr);
pmsg->port = client_addr.sin_port;
if(pthread_create(&tidsend,NULL,send_thread,(void*)pmsg) != 0)
{
fprintf(stderr,"create send_thread error:%s\n",strerror(errno));
free(pmsg);
exit(1);
}

if(pthread_create(&tidrecv,NULL,recv_thread,(void*)pmsg) != 0)
{
fprintf(stderr,"create recv_thread error:%s\n",strerror(errno));
free(pmsg);
exit(1);
}
pthread_join(tidsend,NULL);
pthread_join(tidrecv,NULL);
printf("send and recv threads both returned!\n\n");
free(pmsg);
close(newsockfd);
}
close(sockfd);

exit(0);

}


Client.c

#include "ImmediaCommunicate.h"

int main(int argc,char *argv[])
{
if(argc != 3)
{
fprintf(stderr,"%s lack parameter. Try angain with right Ip and port num.\n",argv[0]);
exit(0);
}
/* create socket*/
int sockfd;
if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"create socket fialed:%s\n",strerror(errno));
exit(0);
}
printf("mark\n");
/*get server's ip and port*/
in_addr_t ip;
if((ip = inet_addr(argv[1]))==INADDR_NONE)
{
fprintf(stderr,"get ip failed:%s\n",strerror(errno));
exit(1);
}
int port;
if((port = atoi(argv[2]))<0)
{
fprintf(stderr,"port parameter error!%s\n",strerror(errno));
exit(1);
}
/*create address*/
struct sockaddr_in server_addr;
memset((void*)&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr =htonl(ip);

printf("connecting server slide...\n");
/*connect and bind locale socket to default address*/
if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))== -1)
{
fprintf(stderr,"connetc error:%s\n",strerror(errno));
exit(1);
}
printf("connetc server slide success...\n");
/*connect success ,now communicate with server.create send and recv thread*/
MSG *pmsg = malloc(sizeof(MSG));
pmsg->sockfd = sockfd;
pmsg->ipstr = argv[1];
pmsg->port = port;
pthread_t tidsend;
pthread_t tidrecv;
if(pthread_create(&tidsend,NULL,send_thread,(void*)pmsg)!=0)
{
fprintf(stderr,"create send_thread failed: %s\n",strerror(errno));
free(pmsg);
exit(0);
}

if(pthread_create(&tidrecv,NULL,recv_thread,(void*)pmsg)!=0)
{
fprintf(stderr,"create recv_thread failed: %s\n",strerror(errno));
free(pmsg);
exit(0);
}

pthread_join(tidsend,NULL);
pthread_join(tidrecv,NULL);
close(sockfd);
printf("send and recv threads both returned!\n");

return 0;
}

还有一个.c文件和.h文件没贴上来不过对于理解没影响。

服务端和客户端在本地是可以正常的相互通信的。如果服务端和客户端在不主机上,服务端一直显示:waiting for connect from a client...
客户端一直显示:connecting server slide...

我不知道问题出在哪里了

...全文
3326 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
东大学子 2013-10-28
  • 打赏
  • 举报
回复
引用 10 楼 enlinux 的回复:
[quote=引用 8 楼 luciferisnotsatan 的回复:] 引用 7 楼 enlinux 的回复:在单机上,IP由虚拟机NAT转发,知道单机三方的IP地址,但2台机器的虚拟机上,通讯需要路由器,但路由器不知道虚拟机的ip,所以网络不可达。解决办法:server不要用虚拟机 虚拟机网卡选桥接就可以了。
请教下,虚拟机网卡选桥接这用的是哪个协议 [/quote] 我也遇到同样问题,请问解决了么?
子善旬 2012-11-21
  • 打赏
  • 举报
回复
引用 8 楼 luciferisnotsatan 的回复:
引用 7 楼 enlinux 的回复:在单机上,IP由虚拟机NAT转发,知道单机三方的IP地址,但2台机器的虚拟机上,通讯需要路由器,但路由器不知道虚拟机的ip,所以网络不可达。解决办法:server不要用虚拟机 虚拟机网卡选桥接就可以了。
请教下,虚拟机网卡选桥接这用的是哪个协议
雷格 2012-11-21
  • 打赏
  • 举报
回复
问题搞定了,是因为客户端指定IP的时候没用网络字节顺序
luciferisnotsatan 2012-11-20
  • 打赏
  • 举报
回复
引用 7 楼 enlinux 的回复:
在单机上,IP由虚拟机NAT转发,知道单机三方的IP地址,但2台机器的虚拟机上,通讯需要路由器,但路由器不知道虚拟机的ip,所以网络不可达。解决办法:server不要用虚拟机
虚拟机网卡选桥接就可以了。
子善旬 2012-11-19
  • 打赏
  • 举报
回复
在单机上,IP由虚拟机NAT转发,知道单机三方的IP地址,但2台机器的虚拟机上,通讯需要路由器,但路由器不知道虚拟机的ip,所以网络不可达。解决办法:server不要用虚拟机
子善旬 2012-11-19
  • 打赏
  • 举报
回复
可是两台机子就连不通了。因为我用的是windows系统,所以实在虚拟机中编写并测试的。在一台虚拟机上可以相互通信。分别放到两台虚拟机上就连接不上了。服务端一直处于等待连接状态,客户端一值处于尝试连接中。两台主机的防火墙都关闭了。 在单机上,有虚拟机NAT转发,直到虚拟机地址,但2台机器的虚拟机上,通讯需要路由器,但路由器不直到虚拟机的ip,所以网络不可达。解决办法:server不要用虚拟机
雷格 2012-11-19
  • 打赏
  • 举报
回复
引用 3 楼 luciferisnotsatan 的回复:
引用 2 楼 leigema 的回复:引用 1 楼 xumaojun 的回复:客户端所在的虚拟机上能否ping通服务器所在的虚拟机的监听的端口?所有确保两个虚拟机通信正常,再调试程序问题? 现在两个虚拟机之间可以ping通了,它们的ip只相差最后一位。应该是在同一网段内。 现在客户端显示的是 Network unreachable 都可以ping通了,为什么会这……
我在ubuntu下用sudo ufw disable关防火墙的。再用ufw status查看的结果是:不活动 这是关了吧? 我明天好好看看 UNIX网络编程卷一的前3章,再来看这个问题。
xumaojun 2012-11-19
  • 打赏
  • 举报
回复
客户端所在的虚拟机上能否ping通服务器所在的虚拟机的监听的端口?所有确保两个虚拟机通信正常,再调试程序问题?
xumaojun 2012-11-19
  • 打赏
  • 举报
回复
nc检测端口的用法 nc -z -w 10 %IP% %PORT% -z表示检测或者扫描端口 -w表示超时时间 -u表示使用UDP协议 例如: [@s136.ipcpu.com ~]# nc -z -w 10 -u 8.8.8.8 53 Connection to 8.8.8.8 53 port [udp/domain] succeeded! [@s136.ipcpu.com ~]# nc -z -w 10 8.8.8.8 53 Connection to 8.8.8.8 53 port [tcp/domain] succeeded! [@s136.ipcpu.com ~]# echo $? 0 [@s136.ipcpu.com ~]# nc -z -w 10 8.8.8.7 53 [@s136.ipcpu.com ~]# echo $? 1 [@s136.ipcpu.com ~]# 端口成功联通返回值是0,提示succeeded;否则返回1,不提示任何数据
luciferisnotsatan 2012-11-19
  • 打赏
  • 举报
回复
引用 2 楼 leigema 的回复:
引用 1 楼 xumaojun 的回复:客户端所在的虚拟机上能否ping通服务器所在的虚拟机的监听的端口?所有确保两个虚拟机通信正常,再调试程序问题? 现在两个虚拟机之间可以ping通了,它们的ip只相差最后一位。应该是在同一网段内。 现在客户端显示的是 Network unreachable 都可以ping通了,为什么会这样?
可能端口到不了,你确定防火墙给关了?
雷格 2012-11-19
  • 打赏
  • 举报
回复
引用 1 楼 xumaojun 的回复:
客户端所在的虚拟机上能否ping通服务器所在的虚拟机的监听的端口?所有确保两个虚拟机通信正常,再调试程序问题?
现在两个虚拟机之间可以ping通了,它们的ip只相差最后一位。应该是在同一网段内。 现在客户端显示的是 Network unreachable 都可以ping通了,为什么会这样?

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧