当前位置:网站首页>Socket socket programming
Socket socket programming
2022-07-07 11:08:00 【Exy-】
Catalog
common socket API
// establish socket File descriptor (TCP/UDP, client + The server )
int socket(int domain, int type, int protocol);
// Binding port number (TCP/UDP, The server )
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
// Start listening socket (TCP, The server )
int listen(int socket, int backlog);
// Receiving request (TCP, The server )
int accept(int socket, struct sockaddr* address,socklen_t* address_len);
// Establishing a connection (TCP, client )
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
sockaddr structure
- IPv4 and IPv6 The address format of is defined in netinet/in.h in ,IPv4 Address use sockaddr_in The structure represents , Include 16 Bit address type , 16 Bit port number and 32 position IP Address .
- IPv4、IPv6 Address types are defined as constants AF_INET、AF_INET6. such , Just get something sockaddr The first address of the structure , You don't need to know what kind of sockaddr Structure , You can determine the content of the structure according to the address type field .
- socket API You can use it all struct sockaddr * Type said , It needs to be converted into sockaddr_in; That's good This is the universality of the program , You can receive IPv4, IPv6, as well as UNIX Domain Socket All kinds of sockaddr Structure pointer as a parameter ;
encapsulation UDPSocket
//udpsocket.cpp
#include<cstdio>
#include<unistd.h>
#include<iostream>
#include<string.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/socket.h>
using namespace std;
class UdpSocket
{
public:
UdpSocket()
:_sockfd(-1)
{}
bool Socket(){
_sockfd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(_sockfd<0)
{
perror("socket error");
return false;
}
return true;
}
bool Bind(const std::string &ip,int port)
{
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=inet_addr(ip.c_str());
socklen_t len=sizeof(struct sockaddr_in);
if(bind(_sockfd,(struct sockaddr*)&addr,len)<0)
{
perror("bind error");
return false;
}
return true;
}
bool Send(const std::string &data,const std::string &ip,int port)
{
struct sockaddr_in peeraddr;
peeraddr.sin_family=AF_INET;
peeraddr.sin_port=htons(port);
peeraddr.sin_addr.s_addr=inet_addr(ip.c_str());
socklen_t len=sizeof(struct sockaddr_in);
int ret=sendto(_sockfd,&data[0],data.size(),0,(struct sockaddr*)&peeraddr,len);
if(ret<0)
{
perror("sendto error");
return false;
}
return true;
}
bool Recv(std::string *buf,std::string *ip=NULL,int *port=NULL)
{
struct sockaddr_in peeraddr;
socklen_t len=sizeof(struct sockaddr_in);
char tmp[4096]={0};
int ret=recvfrom(_sockfd,tmp,4095,0,(struct sockaddr*)&peeraddr,&len);
if(ret<0)
{
perror("recvfrom error");
return false;
}
buf->assign(tmp,ret);
if(ip!=NULL)
*ip=inet_ntoa(peeraddr.sin_addr);
if(port!=NULL)
*port=ntohs(peeraddr.sin_port);
return true;
}
bool Close()
{
if(_sockfd>0)
{
close(_sockfd);
_sockfd=-1;
}
return true;
}
private:
int _sockfd;
};
udp Client code
#include<iostream>
#include<cstdlib>
#include"udpsocket.cpp"
#include<string.h>
#define CHECK_RET(q) if((q)==false){return -1;}
using namespace std;
int main(int argc,char*argv[])
{
if(argc<3)
{
cout<<"usage: Please enter the server address information !\n";
cout<<"\t./udp_client 192.168.1.2 9000\n";
return -1;
}
string srv_ip=argv[1];
int srv_port=atoi(argv[2]);
UdpSocket sock;
CHECK_RET(sock.Socket());
while(1)
{
string buf;
cout<<"client input";
cin>>buf;
CHECK_RET(sock.Send(buf,srv_ip,srv_port));
buf.clear();
CHECK_RET(sock.Recv(&buf));
cout<<"sever response: "<<buf<<endl;
}
sock.Close();
return 0;
}
udp Server code
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<string.h>
int main(int argc,char*argv[])
{
if(argc<3)
{
printf("usage: ./udp_srv 192.168.1.2 9000\n");
return -1;
}
char* srv_ip=argv[1];
int srv_port=atoi(argv[2]);
int sockfd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sockfd<0)
{
perror("socket error");
return -1;
}
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(srv_port);
addr.sin_addr.s_addr=inet_addr(srv_ip);
socklen_t len=sizeof(addr);
int ret=bind(sockfd,(struct sockaddr*)&addr,len);
if(ret<0)
{
close(sockfd);
perror("bind error");
return -1;
}
//3. receive data , Receive the peer address
while(1){
char buf[4096]={0};
struct sockaddr_in client_addr;
len=sizeof(client_addr);
ret=recvfrom(sockfd,buf,4095,0,(struct sockaddr*)&client_addr,&len);
if(ret<0)
{
close(sockfd);
perror("recvfrom error");
return -1;
}
printf("%s:%d - %s\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port),buf);
printf("server input");
fflush(stdout);
memset(buf,0x00,4096);
scanf("%s",buf);
ret=sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&client_addr,len);
if(ret<0)
{
close(sockfd);
perror("sendto error");
return -1;
}
}
close(sockfd);
return 0;
}
among inet_pton and inet_ntop Not only can it be converted IPv4 Of in_addr, You can also convert IPv6 Of in6_addr, So the function interface is void *addrptr.
encapsulation TCPSocket
#include<cstdio>
#include<iostream>
#include<stdlib.h>
#include<unistd.h>
#include<string>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<stdio.h>
#define MAX_LISTEN 5
#define CHECK_RET(q) if((q)==false){return -1;}
class TcpSocket
{
public:
TcpSocket()
:_sockfd(-1)
{}
bool Socket()
{
_sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(_sockfd<0)
{
perror("socket error");
return false;
}
return true;
}
bool Bind(const std::string&ip,int port)
{
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=inet_addr(ip.c_str());
socklen_t len=sizeof(addr);
if(bind(_sockfd,(struct sockaddr*)&addr,len)<0)
{
perror("bind error");
return false;
}
return true;
}
bool Listen(int backlog=MAX_LISTEN)
{
if(listen(_sockfd,backlog)<0)
{
perror("listen error");
return false;
}
return true;
}
bool Connect(const std::string &srv_ip,int srv_port)
{
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(srv_port);
addr.sin_addr.s_addr=inet_addr(srv_ip.c_str());
socklen_t len=sizeof(addr);
if(connect(_sockfd,(struct sockaddr*)&addr,len)<0)
{
perror("connect error");
return false;
}
return false;
}
bool Accept(TcpSocket *new_sock,std::string *cli_ip,int *cli_port)
{
struct sockaddr_in addr;
socklen_t len=sizeof(addr);
int newfd=accept(_sockfd,(struct sockaddr*)&addr,&len);
if(newfd<0)
{
perror("accept error");
return false;
}
std::cout<<"new connect:"<<inet_ntoa(addr.sin_addr)<<":"<<ntohs(addr.sin_port)<<"\n";
new_sock->_sockfd=newfd;
if(cli_ip!=NULL)
{
*cli_ip=inet_ntoa(addr.sin_addr);
}
if(cli_port!=NULL)
{
*cli_port=ntohs(addr.sin_port);
}
return true;
}
bool Send(const std::string &data)
{
ssize_t ret=send(_sockfd,data.c_str(),data.size(),0);
{
if(ret<0)
{
perror("send error");
return false;
}
return true;
}
}
bool Recv(std::string *buf)
{
char tmp[4096]={0};
ssize_t ret=recv(_sockfd,tmp,4096,0);
if(ret<0)
{
perror("recv error");
return false;
}
else if(ret==0)
{
std::cout<<"perr shutdown!\n";
return false;
}
buf->assign(tmp,ret);// from tmp Intercept data of specified length , Prevent the end of string mark in the data ;
return true;
}
bool Close()
{
if(_sockfd>0)
{
close(_sockfd);
_sockfd=-1;
}
return true;
}
private:
int _sockfd;
};
tcp Server side
#include"tcp_socket.cpp"
int main(int argc,char *argv[])
{
if(argc<2)
{
std::cout<<"usage: ./tcp_srv 9000\n";
return -1;
}
int port = std::stoi(argv[1]);
// Create socket
TcpSocket lst_sock;
CHECK_RET(lst_sock.Socket());
// Binding address information
CHECK_RET(lst_sock.Bind("0.0.0.0",port));
// Start listening
CHECK_RET(lst_sock.Listen());
while(1)
{
TcpSocket new_sock;
std::string cli_ip;
int cli_port;
CHECK_RET(lst_sock.Accept(&new_sock,&cli_ip,&cli_port));
std::cout<<"new connect: "<<cli_ip<<":"<<cli_port<<"\n";
std::string buf;
new_sock.Recv(&buf);// Communicate with the specified client by creating a new connection
std::cout<<"client say: "<<buf<<std::endl;
buf.clear();
std::cout<<"server say: ";
std::cin>>buf;
new_sock.Send(buf);
}
lst_sock.Close();
return 0;
}
tcp client
#include"tcp_socket.cpp"
int main(int argc,char*argv[])
{
// Although the client does not actively bind addresses , But you must know the address of the server ;
if(argc<3)
{
std::cout<<"usage: arg error\n";
std::cout<<"\t ./tcp_cli 192.168.2.2 9000\n";
return -1;
}
int srv_port=std::stoi(argv[2]);
std::string srv_ip=argv[1];
TcpSocket sock;
// Create socket
CHECK_RET(sock.Socket());
// Send a connection request to the server
CHECK_RET(sock.Connect(srv_ip,srv_port));
while(1)
{
std::string data;
std::cout<<"client say:";
fflush(stdout);
std::cin>>data;
sock.Send(data);
CHECK_RET(sock.Send(data));
data.clear();
CHECK_RET(sock.Recv(&data));
std::cout<<"server say:"<< data<<std::endl;
}
// Close socket
sock.Close();
}
边栏推荐
- [pyqt] the cellwidget in tablewidget uses signal and slot mechanism
- Installation and configuration of slurm resource management and job scheduling system
- Deconstruction and assignment of variables
- JS implementation chain call
- The eighth training assignment
- uniapp 在onLaunch中跳转页面后,点击事件失效解决方法
- 2022.7.4DAY596
- 從色情直播到直播電商
- IDEA快捷键大全
- 2022.7.6DAY598
猜你喜欢
【推荐系统 01】Rechub
From pornographic live broadcast to live broadcast E-commerce
【亲测可行】error while loading shared libraries的解决方案
【OneNote】无法连接到网络,无法同步问题
How to successfully pass the senior system architecture designer in the second half of the year?
從色情直播到直播電商
Ping tool ICMP message learning
软考信息处理技术员有哪些备考资料与方法?
Deep understanding of Apache Hudi asynchronous indexing mechanism
seata 1.3.0 四種模式解决分布式事務(AT、TCC、SAGA、XA)
随机推荐
uniCloud
Unity script generates configurable files and loads
Is the soft test intermediate useful??
Unity websocket server
Galaxy Kirin desktop operating system installation postgresql13 (source code installation)
Still cannot find RPC dispatcher table failed to connect in virtual KD
Ping tool ICMP message learning
【机器学习 03】拉格朗日乘子法
Transaction rolled back because it has been marked as rollback-only解决
SQL Server knowledge gathering 9: modifying data
Network engineer test questions and answers in May of the first half of 2022
Network foundation (1)
2022.7.3DAY595
【pyqt】tableWidget里的cellWidget使用信号与槽机制
[installation system] U disk installation system tutorial, using UltraISO to make U disk startup disk
Qtcreator sets multiple qmake
[STM32] actual combat 3.1 - drive 42 stepper motors with STM32 and tb6600 drivers (I)
seata 1.3.0 四種模式解决分布式事務(AT、TCC、SAGA、XA)
CSAPP bomb lab parsing
Interprocess communication (IPC)