socket---TCP通信
TCP通信流程的编写:
通信流程:
Server:
1.创建套接字
2.为套接字绑定地址信息
3.开始监听
告诉系统可以开始处理客户端的连接请求。
系统会为每一个新客户创建一个新的套接字
4.获取新建连接
5. 收发数据(使用的是新建的套接字)
6. 关闭套接字
Client:
1.创建套接字
2. 为套接字绑定地址信息(不推荐主动绑定)
3.向服务端发起连接请求(开始监听之后)
4.收发数据
5.关闭套接字
接口认识:
1.创建套接字:int socket(int domain, int type, int protocol);
2.绑定地址:int bind(int sockfd, struct sockaddr *addr,socklen_t addrlen);
3.开始监听:int listen(int sockfd,int backlog);
sockfd:描述符backlog:服务端能够在同一时间处理的最大连接数
已完成连接队列的节点数量=backlog+1
tcpsocket.hpp
#include<cstdio> #include<iostream>#include<string>#include<unistd.h>#include<arpa/inet.h>#include<netinet/in.h>#include<sys/socket.h>#define CHECK_RET(q) if((q)==false){return -1;}#define LISTEN_BACKLOG 5class TcpSocket{private:int _sockfd; //套接字描述符public:TcpSocket():_sockfd(-1){}//1.建立套接字bool Socket(){//int socket(地址域类型,套接字类型,协议类型)_sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(_sockfd<0){perror("socket error");return false;}return true;}//2.套接字绑定地址信息bool Bind(const std::string &ip,const uint16_t port){sockaddr_in addr; //建立IPv4结构体addr.sin_family=AF_INET; //设置地址域类型为IPv4addr.sin_port=htons(port); //主机字节序端口转换为网络字节序端口addr.sin_addr.s_addr=inet_addr(&ip[0]); //将点分十进制转换为网络字节序socklen_t len=sizeof(sockaddr_in);//int bind(操作句柄,当前地址信息,地址信息长度)int ret=bind(_sockfd,(sockaddr*)&addr,len);if(ret<0){perror("bind error");return false;}return true;}//3.开始监听//int listen(描述符,同一时间连接数)bool Listen(int backlog=LISTEN_BACKLOG){int ret=listen(_sockfd,backlog);if(ret<0){perror("listen error");return false;}return true;}//4.客户端发送连接请求bool Connect(const std::string &ip,const uint16_t port){//int connect(描述符,服务端地址,地址长度)sockaddr_in addr; //创建IPv4结构体addr.sin_family=AF_INET; //地址域类型为IPv4addr.sin_port=htons(port); //主机字节序转换为网络字节序addr.sin_addr.s_addr=inet_addr(&ip[0]); //将点分十进制主机字节序转换为网络字节序socklen_t len=sizeof(sockaddr_in);int ret=connect(_sockfd,(sockaddr*)&addr,len);if(ret<0){perror("connect error");return false;}return true;}//5.服务端获取新连接bool Accept(TcpSocket *sock,std::string *ip=NULL,uint16_t *port=NULL){//int accept(监听套接字,客户端地址,长度)sockaddr_in addr; socklen_t len=sizeof(sockaddr_in);int newfd=accept(_sockfd,(sockaddr*)&addr,&len);if(newfd<0){perror("accept error");return false;}sock->_sockfd=newfd;if(ip!=NULL){ //新连接成功*ip=inet_ntoa(addr.sin_addr);} if(port!=NULL){ //新连接成功*port=ntohs(addr.sin_port);}return true;}//收发数据(tcp通信因为socket包含完整五元组因此不需要指定地址)bool Recv(std::string *buf){//int recv(描述符,空间,数据长度,标志位)char tmp[4096]={0};int ret=recv(_sockfd,tmp,4096,0);if(ret<0){perror("recv error");return false;}else if(ret==0){printf("peer shutdown");return false;}buf->assign(tmp,ret);return true;}bool Send(const std::string &data){//int send(描述符,数据,长度,标志位)int total=0;while(total<data.size()){ int ret=send(_sockfd,&data[0]+total,data.size()-total,0);if(ret<0){perror("send error");return false;}total+=ret;}return true;}//关闭连接bool Close(){if(_sockfd!=-1){close(_sockfd);}return true;}};
tcp_cli.cpp
1 #include"tcpsocket.hpp"2 3 int main(int argc,char *argv[])4 {5 //通过参数传入要连接的服务器的地址信息6 if(argc!=3){7 printf("usage:./tcp_cli srvip srvport\n");8 return -1;9 }10 std::string srvip=argv[1];11 uint16_t srvport=std::stoi(argv[2]); //将字符串转换为十进制12 13 TcpSocket cli_sock;14 //1.创建套接字15 CHECK_RET(cli_sock.Socket());16 //2.绑定地址信息(不推荐)_17 //3.向服务端发起连接18 CHECK_RET(cli_sock.Connect(srvip,srvport));19 while(1){20 //4.接收数据21 std::string buf;22 std::cout<<"client say:"; 23 std::cin>>buf;24 CHECK_RET(cli_sock.Send(buf));25 26 buf.clear();27 CHECK_RET(cli_sock.Recv(&buf));28 std::cout<<"server say:"<<buf<<std::endl;29 }30 //5.关闭套接字31 CHECK_RET(cli_sock.Close());32 return 0;33 }
tcp_srv.cpp
#include "tcpsocket.hpp"int main(int argc, char *argv[])
{//通过程序运行参数指定服务端要绑定的地址// ./tcp_srv 192.168.2.2 9000if (argc != 3) {printf("usage: ./tcp_src 192.168.2.2 9000\n");return -1;}std::string srvip = argv[1];uint16_t srvport = std::stoi(argv[2]);TcpSocket lst_sock;//监听套接字//1. 创建套接字CHECK_RET(lst_sock.Socket());//2. 绑定地址信息CHECK_RET(lst_sock.Bind(srvip, srvport));//3. 开始监听CHECK_RET(lst_sock.Listen());while(1) {//4. 获取新建连接TcpSocket clisock;std::string cliip;uint16_t cliport;bool ret = lst_sock.Accept(&clisock, &cliip,&cliport);if (ret == false) {continue;}std::cout<<"get newconn:"<< cliip<<"-"<<cliport<<"\n";//5. 收发数据--使用获取的新建套接字进行通信std::string buf;ret = clisock.Recv(&buf);if (ret == false) {clisock.Close();continue;}std::cout << "client say: " << buf << std::endl;buf.clear();std::cout << "server say: ";std::cin >> buf;ret = clisock.Send(buf);if (ret == false) {clisock.Close();}}//6. 关闭套接字lst_sock.Close();
}
socket---TCP通信相关推荐
- 使用NIO实现异步非阻塞Socket tcp通信
使用NIO实现异步非阻塞Socket tcp通信 一.BIO与NIO IO(BIO)和NIO区别:其本质就是阻塞和非阻塞的区别 阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,就会一直等 ...
- socket PHP:详细简单的socket TCP通信PHP实现
如果你想直接运行程序实现效果:请直接看 3.3 本地服务器及客服端程序 1 背景介绍 目标:我希望通过套接字的TCP传输来搭建一个服务器,这个服务器的作用是:接受多个客户端的连接并完成他们的相互通信. ...
- 【iOS】Socket/TCP 通信 发送 NSString 字符串格式数据
Socket/TCP 原理这里就不阐述了,网上一搜一大堆,直接上关键代码. [注]iOS 目前有非常著名的第三方库 CocoaAsyncSocket 可以使用,但是我们项目当时做大数据上报要求直接发送 ...
- PHP使用socket TCP通信对接富途牛牛
富途牛牛APP下载地址: https://www.futunn.com/?lang=zh-CN 1.下载APP后更直观查看接口调用结果 2.可以使用模拟盘去测试相应接口 富途OpenD下载地址: ht ...
- TCP通信的服务器端代码实现
package com.learn.demo01.TCP;import java.io.IOException; import java.io.InputStream; import java.io. ...
- TCP通信的客户端代码实现
package com.learn.demo01.TCP;import java.io.IOException; import java.io.InputStream; import java.io. ...
- Dubbo底层采用Socket进行通信详解
由于Dubbo底层采用Socket进行通信,自己对通信理理论也不是很清楚,所以顺便把通信的知识也学习一下. n 通信理论 计算机与外界的信息交换称为通信.基本的通信方法有并行通信和串行通信两种. 1 ...
- 网络通信-2(TCP通信、ServerSocket、Socket)
1. TCP通信 UDP中只有发送端和接收端,不区分客户端和服务器端.计算机之间可以任意地发送消息. TCP通信严格区分客户端和服务器. 通信时,必须由客户端去连接服务器才能实现通信.服务器不可主动连 ...
- 2-4:套接字(Socket)编程之TCP通信
文章目录 一 TCP通信服务端和客户端--和UDP区别 (1)服务端 (2)客户端 二:TCP通信-多进程/线程 (1)多进程版本 (2)多线程版本 (3)线程池版本 一 TCP通信服务端和客户端-- ...
- 1、Linux中的socket与TCP通信
socket介绍 1.所谓 socket(套接字),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象. 2.一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制. ...
最新文章
- springboot 关于 Class path contains multiple SLF4J bindings.警告的解决
- 13 Django组件- cookie与session
- Leetcode加一 (java、python3)
- java poi设置导出的excel带下拉
- 网络wifi已连接显示不可上网的解决方法教程
- 微信小程序授权文件放到域名根目录下
- 给对话框加上背景皮肤
- Winmerge教程,包括可视化补丁,差异,合并示例
- Element-UI学习之旅-Border边框及图标
- 【日常问题解决】docker 映射端口出错
- POI-HSSFWorkbook合并单元格边框及文字居中问题
- mfc改计算机名称,VC获取并修改计算机屏幕分辨率(MFC)
- MongoDB内嵌文档查询
- 淮南师范学院计算机组成原理试卷,淮南师范学院2008-2009学年度第一学期电机及拖动试卷(2份,有答案)...
- java 延时队列_Java实现简单延迟队列和分布式延迟队列
- ubuntu16.04下安装录屏软件OBS studio
- python SQL语句 占位符
- 关于VMware虚拟机设置NAT后还不能上网解决办法
- DRL经典论坛网络版 一人一句软件使用经验收集2
- 单枪匹马年赚一个亿?靠的是任务管理做得漂亮!