网络套接字编程(TCP协议)
创始人
2024-03-27 08:04:50

文章目录

    • 简单的TCP网络程序
    • 服务器绑定
    • 服务端监听
    • 服务端获取连接
    • 客户端连接服务器
    • 多线程版本的大小写字母转换服务

简单的TCP网络程序

int socket(int domain, int type, int protocol);

参数说明:

domain:创建套接字的域或者叫做协议家族,也就是创建套接字的类型。该参数就相当于struct sockaddr结构的前16个位。如果是本地通信就设置为AF_UNIX,如果是网络通信就设置为AF_INET(IPv4)或AF_INET6(IPv6)。

type:创建套接字时所需的服务类型。其中最常见的服务类型是SOCK_STREAM和SOCK_DGRAM,如果是基于UDP的网络通信,我们采用的就是SOCK_DGRAM,叫做用户数据报服务,如果是基于TCP的网络通信,我们采用的就是SOCK_STREAM,叫做流式套接字,提供的是流式服务。

protocol:创建套接字的协议类别。你可以指明为TCP或UDP,但该字段一般直接设置为0就可以了,设置为0表示的就是默认,此时会根据传入的前两个参数自动推导出你最终需要使用的是哪种协议。

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数说明:

sockfd:创建套接字返回的文件描述符
addr:网络相关的属性
addrlen:传入的addr的长度

服务器绑定

class TcpSever
{void init(){_lisSock = socket(AF_INET, SOCK_STREAM, 0);if (_lisSock == -1){cout << "error socket" << endl;exit(1);}cout << "sucess socket" << endl;//创建服务器信息sockaddr_in server;socklen_t len = sizeof(server);server.sin_family = AF_INET;server.sin_port = htons(_port);_ip == "" ? server.sin_addr.s_addr = INADDR_ANY : inet_aton(_ip.c_str(), &server.sin_addr);//绑定服务器if (bind(_lisSock, (const sockaddr *)&server, len) == -1){cout << "error bind" << endl;exit(1);}cout << "sucess bind" << endl;}private:int _lisSock;    // 监听套接字string _ip;      // 服务器ipu_int16_t _port; // 服务器端口
};

服务端监听

int listen(int sockfd, int backlog);

参数说明:

sockfd:需要设置为监听状态的套接字对应的文件描述符。
backlog:全连接队列的最大长度。如果有多个客户端同时发来连接请求,此时未被服务器处理的连接就会放入连接队列,该参数代表的就是这个全连接队列的最大长度,一般不要设置太大,设置为5或10即可。

//监听_sock
if (listen(_lisSock, 5) == -1)
{cout << "error listen" << endl;exit(1);}
cout << "sucess listen" << endl;

服务端获取连接

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

参数说明:

sockfd:特定的监听套接字,表示从该监听套接字中获取连接。
addr:对端网络相关的属性信息,包括协议家族、IP地址、端口号等。
addrlen:调用时传入期望读取的addr结构体的长度,返回时代表实际读取到的addr结构体的长度,这是一个输入输出型参数。

void load()
{//监听_sockif (listen(_lisSock, 5) == -1){cout << "error listen" << endl;exit(1);}cout << "sucess listen" << endl;while (1){sockaddr_in client;socklen_t len = sizeof(client);int sock = accept(_lisSock, (sockaddr *)&client, &len);if (sock == -1){cout << "error sock" << endl;exit(1);}cout << "succes sock" << endl;
}

客户端连接服务器

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数说明:

sockfd:特定的套接字,表示通过该套接字发起连接请求。
addr:对端网络相关的属性信息,包括协议家族、IP地址、端口号等。
addrlen:传入的addr结构体的长度。

class TcpClient
{public:TcpClient(string serIp,uint16_t serPort):_serIp(serIp),_serPort(serPort){}void start(){//套接字int _sock = socket(AF_INET,SOCK_STREAM,0);sockaddr_in server;socklen_t len=sizeof(server);server.sin_family=AF_INET;server.sin_port=htons(_serPort);inet_aton(_serIp.c_str(),&server.sin_addr);if(connect(_sock,(const sockaddr*)&server,len) == -1){cout<<"error connet"<close(_sock);}
private:int _sock; //套接字string _serIp; // 服务器ipuint16_t _serPort; //服务器端口};

多线程版本的大小写字母转换服务

server.hpp

class TcpSever;struct Data
{Data(int sock,const string& ip,uint16_t port,TcpSever* TcpServer_this):_sock(sock),_ip(ip),_port(port),_TcpServer_this(TcpServer_this){}int _sock;string _ip;uint16_t _port;TcpSever* _TcpServer_this;
};class TcpSever
{
public:TcpSever(u_int16_t port, string ip = "") : _lisSock(-1), _port(port), _ip(ip){}void init(){_lisSock = socket(AF_INET, SOCK_STREAM, 0);if (_lisSock == -1){cout << "error socket" << endl;exit(1);}cout << "sucess socket" << endl;//创建服务器信息sockaddr_in server;socklen_t len = sizeof(server);server.sin_family = AF_INET;server.sin_port = htons(_port);_ip == "" ? server.sin_addr.s_addr = INADDR_ANY : inet_aton(_ip.c_str(), &server.sin_addr);//绑定服务器if (bind(_lisSock, (const sockaddr *)&server, len) == -1){cout << "error bind" << endl;exit(1);}cout << "sucess bind" << endl;// 线程池的创建_tp=threadPool::getinstance();}void load(){//监听_sockif (listen(_lisSock, 5) == -1){cout << "error listen" << endl;exit(1);}cout << "sucess listen" << endl;while (1){sockaddr_in client;socklen_t len = sizeof(client);int sock = accept(_lisSock, (sockaddr *)&client, &len);if (sock == -1){cout << "error sock" << endl;exit(1);}cout << "succes sock" << endl;string client_ip = inet_ntoa(client.sin_addr);u_int16_t client_port = ntohs(client.sin_port);// 多线程版本Data d(sock,client_ip,client_port,this);pthread_t tid;pthread_create(&tid,nullptr,Routine,&d);}static void* Routine(void* args){Data* pd = (Data*) args;pd->_TcpServer_this->LotoUp(pd->_sock,pd->_ip,pd->_port);}//翻译大小写void LotoUp(int sock, string ip, u_int16_t port){cout<<"sucess LotoUp"<char inbuf[1024];ssize_t s = read(sock, inbuf, 1024);if (s > 0){inbuf[s]='\0';cout<<"before:"<inbuf[i] = toupper(inbuf[i]);}cout<<"after:"<cout << ip << ":" << port << "   quit LotoUp" << endl;break;}else{cout << ip << ":" << port << "   error LotoUp" << endl;break;}}close(sock);}~TcpSever(){}private:int _lisSock;    // 监听套接字string _ip;      // 服务器ipu_int16_t _port; // 服务器端口
};int main()
{TcpSever server(8081);server.init();server.load();return 0;
}

client.hpp


class TcpClient
{public:TcpClient(string serIp,uint16_t serPort):_serIp(serIp),_serPort(serPort){}void start(){//套接字int _sock = socket(AF_INET,SOCK_STREAM,0);sockaddr_in server;socklen_t len=sizeof(server);server.sin_family=AF_INET;server.sin_port=htons(_serPort);inet_aton(_serIp.c_str(),&server.sin_addr);if(connect(_sock,(const sockaddr*)&server,len) == -1){cout<<"error connet"<   string outbuf;outbuf.clear();cout<<"请输入内容>>>";getline(cin,outbuf);if(outbuf == "quit"){quit=true;}ssize_t s = write(_sock,outbuf.c_str(),outbuf.size());if(s>0){char inbuf[1024];ssize_t rs = read(_sock,inbuf,sizeof(inbuf));inbuf[rs]=0;cout<close(_sock);}
private:int _sock; //套接字string _serIp; // 服务器ipuint16_t _serPort; //服务器端口};int main()
{TcpClient client("127.0.0.1",8081);client.start();return 0;
}

效果
在这里插入图片描述
在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...