INADDR_ANY
,具体代码如下:
bool TcpServerInit(){// 绑定struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = INADDR_ANY;if (bind(_listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0){cout << "bind fail" << endl;return false;}cout << "bind success" << endl;}
将套接字设置为监听状态这里就需要用的listen
这个接口,让套接字处于监听状态,然后可以去监听连接的到来代码也很简单,具体如下:
bool TcpServerInit(){// 将套接字设置为监听状态if (listen(_listen_sock, BACK_LOG) < 0){cout << "listen fail" << endl;return false;}cout << "listen success" << endl;}
循环获取连接听套接字通过accept获取连接,一次获取连接失败不要直接将服务端关闭,而是重新去获取连接就好,因为获取一个连接失败而直接关闭服务端,带来的损失是很大的,所以只需要重新获取连接即可,返回的用于通信套接字记录下来,进行通信,然后可以用多种方式为各种连接连接提供服务,具体服务方式后面细说,先看获取连接的一部分代码:
void loop(){struct sockaddr_in peer;// 获取远端端口号和ip信息socklen_t len = sizeof(peer);while (1){// 获取链接// sock 是进行通信的一个套接字_listen_sock 是进行监听获取链接的一个套接字int sock = accept(_listen_sock, (struct sockaddr*)&peer, &len);if (sock < 0){cout << "accept fail, continue accept" << endl;continue;}// 提供服务 service 后面介绍}}
客户端整体框架和服务端一样,封装一个类描述,类成员有服务端ip、服务端绑定的端口号以及自身套接字,代码如下:
【TCP套接字编写,多进程多线程版本 Linux网络通信】class TcpClient{public:TcpClient(string ip, int port):_server_ip(ip),_server_port(port),_sock(-1){}~TcpClient(){if (_sock >= 0) close(_sock);}private:string _server_ip;int _server_port;int _sock;};
客户端初始化客户端的初始化只需要创建套接字即可,不需要绑定端口号,发起连接请求的时候,会自动给客户端分配一个端口号 。创建套接字和服务端是一样的,代码如下:
bool TcpClientInit(){// 创建套接字_sock = socket(AF_INET, SOCK_STREAM, 0);if (_sock < 0){cout << "socket creat fail" << endl;return false;}cout << "socket creat succes, sock: " << _sock << endl;return true;}
客户端启动发起连接请求使用connect
函数,想服务端发起连接请求,注意,调用这个函数之前,需要先填充好服务端的信息,有协议家族、端口号和IP,请求连接失败直接退出进程,重新启动进程即可,连接成功之后就可以像服务端发起各自的服务请求(后面介绍),代码如下:
void TcpClientStart(){// 连接服务器struct sockaddr_in peer;peer.sin_family = AF_INET;peer.sin_port = htons(_server_port);peer.sin_addr.s_addr = inet_addr(_server_ip.c_str());if (connect(_sock, (struct sockaddr*)&peer, sizeof(peer)) < 0){// 连接失败cerr << "connect fail" <<endl;exit(-1);}cout << "connect success" << endl;Request();// 下面介绍}
发起服务请求请求很简单,只需要让用户输入字符串请求,然后将请求通过write
(send也可以)发送过去,然后创建一个缓冲区,通过read
(recv也可以)读取服务端的响应,这里需要着重介绍一下read
的返回值
- 大于0:实际读取的字节数
- 等于0:读到了文件末尾,说明对端关闭,用在服务端就是客户端关闭,用在客户端就是服务端关闭了,客户端可以直接退出
- 小于0:说明读取失败
经验总结扩展阅读
- 抓包分析 TCP 握手和挥手
- 概念+协议的了解+OSI七层模型,TCP/IP五层协议,网络数据传输流程 Linux--网络基础
- 关于网页实现串口或者TCP通讯的说明
- 如何kill一条TCP连接?
- TCP 序列号和确认号是如何变化的?
- 2d游戏怎么编程(怎么编写一个2d游戏)
- 怎么编写游戏程序(游戏外挂编写教程)
- Tomcat 调优之从 Linux 内核源码层面看 Tcp backlog
- 手写编程语言-如何为 GScript 编写标准库
- 编写HelloWorld并运行