服务器跟客户端的通信问题,想要别人的电脑连接进我的服务器

qq_37867473 2017-03-17 08:30:00
用C++,socket来完成服务器跟客户端的通信问题
刚接触socket,很多细节可能不太明白


用本机当服务器,本机打开客户端连接到本机服务器之后,客户端发送信息给服务器,是成功的
用本机当服务器,别人的电脑当客户端,客户端那边显示,Failed connect()

电脑1的系统:windows7 64位
电脑1的IDE:vs2015

电脑1作为服务端
电脑2作为客户端
电脑1的IP:

电脑2的IP:


服务端源码
#include<winsock2.h>  
#include<stdio.h>
#include<windows.h>
#include<time.h>
#pragma comment(lib,"WS2_32.lib")

int main(int argc, char*argv[])
{
/*加载winsock文件*/
WSADATA wsaData; //WSADATA结构被用来储存调用AfxSocketInit全局函数返回的Windows Sockets初始化信息 定义在Winsock.h
WORD sockVersion = MAKEWORD(2, 0); //使用WINSOCK2版本 512
::WSAStartup(sockVersion, &wsaData); //第一个参数是WINSOCK 版本号,第二个参数是指向WSADATA的指针.
//该函数返回一个INT型值,通过检查这个值来确定初始化是否成功

/*创建服务器端的套接字*/
SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//三个参数分别代表 使用TCP/IP;传输过程使用TCP;不适用其他特殊协议

if (s == INVALID_SOCKET)
{
printf("Failed socket()\n");
::WSACleanup();
system("pause");
return 0;
}

/*socket中装入地址信息*/
sockaddr_in sin;
sin.sin_family = AF_INET; //sin_family指代协议族,在socket编程中只能是AF_INET
sin.sin_port = htons(8800); //表示服务器监听的端口号为13
sin.sin_addr.S_un.S_addr = inet_addr("100.64.73.9"); //存储IP地址,INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。
//sin.sin_addr.S_un.S_addr = INADDR_ANY;
/*绑定地址及端口号*/
if (::bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("Failed bind()\n");
::WSACleanup();
system("pause");
return 0;
}

/*监听客户端的连接请求*/
if (::listen(s, 2) == SOCKET_ERROR)
{
printf("Failed listen()\n");
::WSACleanup();
system("pause");
return 0;
}
sockaddr_in remoteAddr;
int nAddrLen = sizeof(remoteAddr);
SOCKET client;

time_t t = time(0);
char tmp[200];
strftime(tmp, sizeof(tmp), "%Y/%m/%d %X %A\n\t", localtime(&t));//提取系统时间

/*循环接受连接请求*/
while (TRUE)
{
client = ::accept(s, (SOCKADDR*)&remoteAddr, &nAddrLen);//accept默认会阻塞进程,直到有一个客户连接建立后返回,它返回的是一个新可用的套接字,这个套接字是连接套接字。
if (client == INVALID_SOCKET)
{
printf("Failed accept()\n");
continue;
}
printf("接收到一个客户端的连接:%s\r\n\n等待下一个客户端的连接……\n\n", inet_ntoa(sin.sin_addr));

::send(client, tmp, strlen(tmp), 0); /*发送本地时间给客户端*/

::closesocket(client); /*关闭连接*/
}

::closesocket(s);/*关闭套接字*/

::WSACleanup();
system("pause");
return 0;
}




客户端源码
#include<winsock2.h>  
#include<stdio.h>
#include<windows.h>
#pragma comment(lib,"WS2_32.lib")

int main(int argc, char*argv[])
{
/*加载winsock文件*/
WSADATA wsaData;
WORD sockVersion = MAKEWORD(2, 0);
::WSAStartup(sockVersion, &wsaData);

/*创建服务器端的套接字*/
SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (s == INVALID_SOCKET)
{
printf("Failed socket()\n");
::WSACleanup();
system("pause");
}

/*socket中装入地址信息*/
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(8800); /*接收服务器13端口号*/
servAddr.sin_addr.S_un.S_addr = inet_addr("100.64.73.9");/*本地IP地址为127.0.0.1*/

/*连接服务器*/
if (::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1)
{
printf("Failed connect()\n");
::WSACleanup();
system("pause");
}

/*接收数据并打印到屏幕上*/
char buff[256];
int nRecv = ::recv(s, buff, 256, 0);
if (nRecv>0)
{
buff[nRecv] = '\0';
printf("连接成功\n");
printf("接收到数据:%s\n", buff);
//system("pause");
}
return 0;
}
...全文
1293 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
嗯嗯好吧 2018-04-10
  • 打赏
  • 举报
回复
我的客户端和服务端连接同一个wifi就可以通信,但是连接不同的wifi时,就会出现没有到主机的路由的错误,这应该怎么解决呀?急需解答,谢谢
嗯嗯好吧 2018-04-10
  • 打赏
  • 举报
回复
您好,我也有这个问题,应该怎么解决呀,看你们的评论没懂???
qq_37867473 2017-03-19
  • 打赏
  • 举报
回复
太感谢了,激动的无以言表,我看了一些帖子是写成ip:Port,然后把自己的思维局限在客户端和服务端IP必须一样了,一直没有想到客户端IP和端口跟服务端IP和端口不同的问题,还是很感谢,帮了我大忙
ipqtjmqj 2017-03-19
  • 打赏
  • 举报
回复
你在1楼发的代码里不是有htons这个函数的使用吗 假设你把公网地址A:B映射为C:D 则在服务器端的地址填C,监听的端口号填D 在客户端要连接的地址填A,连接的端口填B
ipqtjmqj 2017-03-18
  • 打赏
  • 举报
回复
先让对方ping一下,看看能不能通
qq_37867473 2017-03-18
  • 打赏
  • 举报
回复
有公网IP了,能ping通了 只是每次重新拨号IP会变,我用路由器映射后,只要路由器不关,或者不断电,IP就不会变了,现在就剩下代码要怎么写的问题
qq_37867473 2017-03-18
  • 打赏
  • 举报
回复
引用 5 楼 ipqtjmqj 的回复:
我查了下,100.64.0.0 - 100.127.255.255这个段也是私有地址了。(In April 2012, IANA allocated 100.64.0.0/10 for use in carrier-grade NAT scenarios in RFC 6598) 你确定现在有公网IP了?能ping通了? ------------- inet_addr不是只能转IP地址吗,端口号用htons转
求具体方法,想了一晚上,试了一晚上,快懵了 例如我的外网IP是113.67.XX.XX inet_addr(" ")里要填什么 端口号用htons转是要转么个转法,htons(" ")里填什么
ipqtjmqj 2017-03-18
  • 打赏
  • 举报
回复
我查了下,100.64.0.0 - 100.127.255.255这个段也是私有地址了。(In April 2012, IANA allocated 100.64.0.0/10 for use in carrier-grade NAT scenarios in RFC 6598) 你确定现在有公网IP了?能ping通了? ------------- inet_addr不是只能转IP地址吗,端口号用htons转
qq_37867473 2017-03-18
  • 打赏
  • 举报
回复
知道问题所在了,我之前的IP是内网,我现在换成外网了,但是想用路由接外网,然后我的局域网IP是192.168.0.101 已经在路由器做了映射 服务端口:8888 内部端口:8800 IP地址:192.168.0.101 协议:TCP 代码里的sin_port(端口)要设置成8888还是8800,原因是什么 在sin_addr.S_un.S_addr后面要怎样设置,才能让别人的电脑连到我的服务器,例如 inet_addr("192.168.0.101") 还是inet_addr("192.168.0.101:8888") 还是inet_addr("外网IP:8888"),或者是怎样,试了很多种,都是failed bind
qq_37867473 2017-03-18
  • 打赏
  • 举报
回复
ping不通,没开杀毒软件,关了防火墙,网络发现双方都开了,还是ping不通,很奇怪
qq_37867473 2017-03-17
  • 打赏
  • 举报
回复
服务端没有开防火墙,端口也是可用的,没有被占用,自测可以连上,但是把客户端发给别人,让别人打开客户端来连接到服务端就是连不上 因为::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1 就会提示Failed connect(),求大神,到底为什么别人的网就不行,自测可以

4,387

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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