大家好,我是涛哥。
在局域网内写TCP聊天程序,真的很简单。你可以通过TCP和你的女朋友聊天,图示如下:
涛歌手绘
然而,如果你的女朋友在别的城市,你想写一个软件跟她聊天,那么上面的图示就不行啦。
想一下,这是为什么呢?因为你们都身处在寝室的局域网中,这两个局域网是无法连通的。
那怎么办呢?必须借助一个公网将网络打通。为了进行实际验证,我用的是阿里云的机器。
这个阿里云机器有公网IP地址,于是男女双方都可以和云主机上的服务端通信,图示如下:
涛歌手绘
这里涉及到TCP网络编程,本次我们以Linux环境为例,来介绍TCP客户端和服务端程序。
服务端程序
TCP服务端程序为:
#include<sys/socket.h>
#include<netinet/in.h>
#include <stdio.h>
#include <string.h>
int main()
{
// 创建用于监听的socket
int sockSrv = socket(AF_INET, SOCK_STREAM, 0);
// 本地地址信息
struct sockaddr_in addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_addr.s_addr = INADDR_ANY;
addrSrv.sin_port = htons(8888);
// socket与本地地址绑定
bind(sockSrv, (const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
// 设置socket为监听状态
listen(sockSrv, 5);
struct sockaddr_in addrClient;
int len = sizeof(struct sockaddr_in);
// 等待接受客户端来连接,sockConn是用来与客户端通信的socket(请注意区分用于监听的addrSrv和用于通信的sockConn这两个socket)
int sockConn = accept(sockSrv, (struct sockaddr *)&addrClient, &len);
// 将客户端的IP地址保存下来,并把数据返回客户端
char szSendBuf[100] = {0};
snprintf(szSendBuf, sizeof(szSendBuf), "hello %s, hello client.", inet_ntoa(addrClient.sin_addr));
send(sockConn, szSendBuf, strlen(szSendBuf) + 1, 0);
getchar(); // 卡住
close(sockConn);
close(sockSrv);
return 0;
}
先启动服务端程序,让程序跑起来。
客户端程序
TCP客户端程序为:
#include<sys/socket.h>
#include<netinet/in.h>
#include <stdio.h>
int main()
{
int sockClient = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addrSrv;
addrSrv.sin_addr.s_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(8888);
connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
char szRecvBuf[100] = {0};
recv(sockClient, szRecvBuf, sizeof(szRecvBuf) - 1, 0);
printf("%s\n", szRecvBuf);
getchar();
close(sockClient);
return 0;
}
再启动客户端程序,跑起来。从实际结果来看,客户端和服务端能正常进行通信。
通过利用公网IP打通的方法,男女朋友终于可以在彼此寝室里和对方聊天了。