目录 nc 127.0.0.1 port
01_socket_client.cc
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
int main(int argc,char** argv)
{
//socket-->listenfd
int listenfd=socket(AF_INET,SOCK_STREAM,0);
if(listenfd<0){error(1,errno,"socket");}
//sockaddr_in --> connect
struct sockaddr_in seraddr;
memset(&seraddr,0,sizeof(seraddr));
seraddr.sin_family=AF_INET;
seraddr.sin_port=htons(atoi(argv[2]));//port
seraddr.sin_addr.s_addr=inet_addr(argv[1]);//ip
int ret=connect(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
if(ret<0){error(1,errno,"connect");}
//三次握手建立成功
while(1){
cout<<"propose send message to server"<<endl;
string line;
getline(std::cin,line);
ret=send(listenfd,line.data(),line.size(),0);
if(ret<0){
cout<<"send error"<<endl;
}else if(ret==0){
cout<<"ret==0"<<endl;
}else{
cout<<"send sucessfully"<<endl;
}
char buff[128]={0};
ret=recv(listenfd,buff,sizeof(buff),0);
if(ret<0){
cout<<"recv error"<<endl;
}else if(ret==0){
cout<<"ret==0"<<endl;
}else{
cout<<"recv sucessfully>>>"<<buff<<endl;
}
}
close(listenfd);
return 0;
}
01_socket_server.cc
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
int main(int argc,char** argv)
{
int listenfd=socket(AF_INET,SOCK_STREAM,0);
if(listenfd<0){error(1,errno,"socket");}
//port ip 复用
int opt=1;
int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,
sizeof(opt));
if(retval<0){error(1,errno,"setscockopt");}
int opt2=1;
retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,
sizeof(opt2));
if(retval<0){error(1,errno,"setscockopt2");}
//bind
struct sockaddr_in seraddr;
memset(&seraddr,0,sizeof(seraddr));
seraddr.sin_addr.s_addr=inet_addr(argv[1]);
seraddr.sin_port=htons(atoi(argv[2]));
seraddr.sin_family=AF_INET;
int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
if(ret<0){error(1,errno,"bind");}
//监听
ret=listen(listenfd,128);
if(ret<0){error(1,errno,"listen");}
cout<<"server is listen"<<endl;
//从listenfd队列中取下一个peerfd
int connfd=accept(listenfd,nullptr,nullptr);
if(connfd<0){error(1,errno,"accept");}
//三次握手建立成功
while(1){
char buff[128]={0};
ret=recv(connfd,buff,sizeof(buff),0);
if(ret<0){
cout<<"recv error"<<endl;
}else if(ret==0){
cout<<"ret==0"<<endl;
}else{
cout<<"recv sucessfully>>>"<<buff<<endl;
}
cout<<"propose send message to client"<<endl;
string line;
getline(std::cin,line);
int ret1=send(connfd,line.data(),line.size(),0);
if(ret1<0){
cout<<"send error"<<endl;
}else if(ret1==0){
cout<<"ret1==0"<<endl;
}else{
cout<<"send sucessfully"<<endl;
}
}
close(listenfd);
close(connfd);
return 0;
}
02_select_client.cc
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>
#include <iostream>
#include <string>
#define SERV_IP "192.168.235.128"
#define SERV_PORT 8000
using std::cout;
using std::endl;
using std::string;
int main(int argc,char** argv)
{
//socket-->listenfd
int listenfd=socket(AF_INET,SOCK_STREAM,0);
if(listenfd<0){error(1,errno,"socket");}
//sockaddr_in --> connect
struct sockaddr_in seraddr;
memset(&seraddr,0,sizeof(seraddr));
seraddr.sin_family=AF_INET;
seraddr.sin_port=htons(SERV_PORT);//port
/* seraddr.sin_addr.s_addr=inet_addr(SERV_IP);//ip */
/* inet_pton(listenfd, SERV_IP, &serv_addr.sin_addr.s_addr); */
seraddr.sin_addr.s_addr=htonl(INADDR_ANY);//服务器绑定所有可用接口
int ret=connect(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
if(ret<0){error(1,errno,"connect");}
//三次握手建立成功
char buff[BUFSIZ];//标准io操作的缓冲区大小
int nByte;
while(1){
fgets(buff,sizeof(buff),stdin);//helloc-->hello\n\0
write(listenfd,buff,strlen(buff));//buff有效长度
//buff的内容写入listenfd(套接字本质文件描述符)
nByte=read(listenfd,buff,sizeof(buff));
//读取服务器的响应,nByte实际读取的字节数
write(STDOUT_FILENO,buff,nByte);
//写到stdout
}
close(listenfd);
return 0;
}
02_select_server.cc
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>
#include <sys/select.h>
#include <sys/time.h>
#include <iostream>
#include <string>
#define SERV_PORT 8000
using std::cout;
using std::endl;
using std::string;
int main(int argc,char** argv)
{
int cnt ;//debug
int connfd,sockfd;
int listenfd=socket(AF_INET,SOCK_STREAM,0);
if(listenfd<0){error(1,errno,"socket");}
//port ip 复用
int opt=1;
int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,
sizeof(opt));
if(retval<0){error(1,errno,"setscockopt");}
int opt2=1;
retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,
sizeof(opt2));
if(retval<0){error(1,errno,"setscockopt2");}
//bind
struct sockaddr_in seraddr;
bzero(&seraddr,sizeof(seraddr));/* memset(&seraddr,0,sizeof(seraddr)); */
seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
seraddr.sin_port=htons(SERV_PORT);
seraddr.sin_family=AF_INET;
int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
if(ret<0){error(1,errno,"bind");}
//监听
ret=listen(listenfd,128);
if(ret<0){error(1,errno,"listen");}
cout<<"server is listen"<<endl;
//三次握手建立成功
char buff[BUFSIZ],str[BUFSIZ];
int maxfd=listenfd;
int maxi=-1;
fd_set rset,allset;
int client[FD_SETSIZE];//多1024,可以监视的最大文件描述符数量
//定义在/usr/include/linux/posix_types.h
for(int i=0;i<FD_SETSIZE;++i){
client[i]=-1;
}
FD_ZERO(&allset);
FD_SET(listenfd,&allset);
while(1){
rset=allset;
int nready=select(maxfd+1,&rset,NULL,NULL,NULL);
//nready就绪的描述符数量
if(nready<0){error(1,errno,"select");}
//01,监听到listenfd 新的链接进来
if(FD_ISSET(listenfd,&rset)){
struct sockaddr_in clie_addr;
socklen_t clie_addr_len=sizeof(clie_addr);
//新连接的套接字
connfd=accept(listenfd,(struct sockaddr*)&clie_addr,
&clie_addr_len);
if(connfd==-1){error(1,errno,"accept");}
printf("receive from %s : %d\n",
inet_ntop(AF_FILE,&clie_addr.sin_addr,str,sizeof(str)),
ntohs(clie_addr.sin_port));
//三次握手成功
int i;
for(i=0;i<FD_SETSIZE;++i){
if(client[i]<0){
client[i]=connfd;
break;//加入监听数组
}
}
//==============================
cout<<cnt++<<" "<<i<<endl;
if(i==FD_SETSIZE){
fputs("too much client\n",stderr);
exit(1);
}
FD_SET(connfd,&allset);//添加新连接
//更新maxi,maxfd
if(connfd>maxfd){
maxfd=connfd;
}
if(i>maxi){
maxi=i;
}
//如果nready=1.继续while循环,不用走下面的for循环
if(--nready==0){
continue;
}
}
//02遍历client数组,元素为正,被监听到
//是老连接,可以进行数据发送接受
for(int i=0;i<=maxi;++i){//caution:i<=maxi
if((sockfd=client[i])<0){
continue;
}
//==============================
cout<<cnt++<<" "<<sockfd<<endl;
if(FD_ISSET(sockfd,&rset)){
int nByte=read(sockfd,buff,sizeof(buff));
if(nByte==0){
//数据读完了,(缓冲区没有数据
//连接要断开了
close(sockfd);
cout<<"client "<<sockfd<<" closed connection\n"<<endl;
FD_CLR(sockfd,&allset);
client[i]=-1;
}else if(nByte>0){
for(int j=0;j<nByte;++j){
buff[j]=toupper(buff[j]);//a->A
}
write(sockfd,buff,nByte);
write(STDOUT_FILENO,buff,nByte);
}
if(--nready==0){
break;
}
}
}
}
close(listenfd);
close(connfd);
return 0;
}
03_poll_server.cc
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <error.h>
#include <errno.h>
#include <poll.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <iostream>
#include <string>
#define OPEN_MAX 1024
/* #define SERV_IP "192.168.235.128" */
#define SERV_IP "127.0.0.1"
#define SERV_PORT 7888
using std::cout;
using std::endl;
using std::string;
/* struct pollfd */
/* { */
/* int fd; //要监听的文件描述符 */
/* short events; //待监听的文件描述符的事件 POLLIN/POLLOUT/POLLERR */
/* short revents; //revents & POLLIN */
/* }; */
int main(int argc,char** argv)
{
int cnt ;//debug
int connfd,sockfd;
int listenfd=socket(AF_INET,SOCK_STREAM,0);
if(listenfd<0){error(1,errno,"socket");}
//port ip 复用
int opt=1;
int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,
sizeof(opt));
if(retval<0){error(1,errno,"setscockopt");}
int opt2=1;
retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,
sizeof(opt2));
if(retval<0){error(1,errno,"setscockopt2");}
//bind
struct sockaddr_in seraddr;
bzero(&seraddr,sizeof(seraddr));/* memset(&seraddr,0,sizeof(seraddr)); */
seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
/* seraddr.sin_addr.s_addr=inet_pton( */
/* listenfd, SERV_IP, &seraddr.sin_addr.s_addr); */
seraddr.sin_port=htons(SERV_PORT);
seraddr.sin_family=AF_INET;
int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
if(ret<0){error(1,errno,"bind");}
//监听
ret=listen(listenfd,128);
if(ret<0){error(1,errno,"listen");}
cout<<"server is listen"<<endl;
//三次握手建立成功
char buff[BUFSIZ],str[INET_ADDRSTRLEN];
//IPV4地址的字符串表示形式的最大长度
int maxi=0;
struct pollfd client[OPEN_MAX];
//FOPEN_MAX:一个程序可以同时打开的最大文件流数量
//poll类型,listenfd加入监听
client[0].fd=listenfd;
client[0].events=POLLIN;
for(int i=1;i<OPEN_MAX;++i){//i=0,会把listenfd删掉,注意初始化顺序
client[i].fd=-1;
}
while(1){
int nready=poll(client,maxi+1,-1);
if(nready<0){error(1,errno,"select");}
//==============================
cout<<cnt++<<" "<<client[0].fd<<endl;
//01,监听到listenfd 新的链接进来
if(client[0].revents & POLLIN){
struct sockaddr_in clie_addr;
socklen_t clie_addr_len=sizeof(clie_addr);
//新连接的套接字
connfd=accept(listenfd,(struct sockaddr*)&clie_addr,
&clie_addr_len);
if(connfd==-1){error(1,errno,"accept");}
printf("receive from %s : %d\n",
inet_ntop(AF_FILE,&clie_addr.sin_addr,str,sizeof(str)),
ntohs(clie_addr.sin_port));
//三次握手成功
int i;
for(i=1;i<OPEN_MAX;++i){
if(client[i].fd<0){
client[i].fd=connfd;
break;//加入监听数组
}
}
client[i].events=POLLIN;
//设置要监听的类型
if(i==OPEN_MAX){
fputs("too much client\n",stderr);
exit(1);
}
//更新maxi,fd有新增
if(i>maxi){
maxi=i;
}
//如果nready=1.继续while循环,不用走下面的for循环
if(--nready==0){
continue;
}
}
//02遍历client数组,元素为正,被监听到
//是老连接,可以进行数据发送接受
for(int i=0;i<=maxi;++i){//caution:i<=maxi
if((sockfd=client[i].fd)<0){
continue;
}
//老连接上有数据
if(client[i].revents & POLLIN){
int nByte=read(sockfd,buff,sizeof(buff));
if(nByte<0){
if(errno==ECONNRESET){//客户端被强制关闭
cout<<"client ["<<i<<"] abort connect"<<endl;
close(sockfd);
client[i].fd=-1;
}else{
perror("read nByte=0 error");
}
}else if(nByte>0){
for(int j=0;j<nByte;++j){
buff[j]=toupper(buff[j]);//a->A
}
write(sockfd,buff,nByte);
write(STDOUT_FILENO,buff,nByte);
}else{
close(sockfd);
cout<<"client ["<<i<<"] closed connection"<<endl;
client[i].fd=-1;
}
if(--nready==0){
break;
}
}
}
}
close(listenfd);
close(connfd);
return 0;
}
04_epoll_server.cc
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <error.h>
#include <errno.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <iostream>
#include <string>
#define OPEN_MAX 1024
/* #define SERV_IP "192.168.235.128" */
#define SERV_IP "127.0.0.1"
#define SERV_PORT 6888
using std::cout;
using std::endl;
using std::string;
/* typedef union epoll_data { */
/* void *ptr; */
/* int fd; */
/* uint32_t u32; */
/* uint64_t u64; */
/* } epoll_data_t; */
/* struct epoll_event { */
/* uint32_t events; //EPOLLIN/EPOLLOUT/EPOLLERR */
/* epoll_data_t data; /1* User data variable *1/ */
/* }; */
int main(int argc,char** argv)
{
int cnt ;//debug
int connfd,sockfd;
int listenfd=socket(AF_INET,SOCK_STREAM,0);
if(listenfd<0){error(1,errno,"socket");}
//port ip 复用
int opt=1;
int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,
sizeof(opt));
if(retval<0){error(1,errno,"setscockopt");}
int opt2=1;
retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,
sizeof(opt2));
if(retval<0){error(1,errno,"setscockopt2");}
//bind
struct sockaddr_in seraddr;
bzero(&seraddr,sizeof(seraddr));
seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
/* seraddr.sin_addr.s_addr=inet_pton( */
/* listenfd, SERV_IP, &seraddr.sin_addr.s_addr); */
seraddr.sin_port=htons(SERV_PORT);
seraddr.sin_family=AF_INET;
int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
if(ret<0){error(1,errno,"bind");}
//监听
ret=listen(listenfd,128);
if(ret<0){error(1,errno,"listen");}
cout<<"server is listen"<<endl;
char buff[BUFSIZ],str[INET_ADDRSTRLEN];
//IPV4地址的字符串表示形式的最大长度
//创建红黑树的根节点(红黑树+就绪链表)
int epfd=epoll_create(OPEN_MAX);
/* int epfd=epoll_create1(1); */
if(epfd==-1){error(1,errno,"epoll_create1");}
//赋值evt,listenfd加入监听
struct epoll_event evt,ep[OPEN_MAX];
evt.events=EPOLLIN;
evt.data.fd=listenfd;
ret=epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&evt);
if(ret<0){error(1,errno,"epoll_ctl(add) listenfd");}
while(1){
int nready=epoll_wait(epfd,ep,OPEN_MAX,-1);
if(nready<0){error(1,errno,"select");}
//==============================
cout<<cnt++<<" "<<ep[0].data.fd<<endl;
//递增的ep[0].data.fd,记录的是接收到的事件的数量
//这个上下文中是用来输出当前处理的事件的文件描述符,
//可能会是新连接的文件描述符,所以会看起来是递增的
//02遍历nready
for(int i=0;i<nready;++i){
//异常处理
if(!(ep[i].events & EPOLLIN)){
continue;
}
//监听到listenfd,新连接
//(监听到连接事件)
if(ep[i].data.fd == listenfd){
struct sockaddr_in clie_addr;
socklen_t clie_addr_len=sizeof(clie_addr);
//新连接的套接字
connfd=accept(listenfd,(struct sockaddr*)&clie_addr,
&clie_addr_len);
if(connfd==-1){error(1,errno,"accept");}
printf("receive from %s : %d\n",
inet_ntop(AF_FILE,&clie_addr.sin_addr,str,sizeof(str)),
ntohs(clie_addr.sin_port));
//三次握手成功
//新连接加入监听
evt.events=EPOLLIN;
evt.data.fd=connfd;
ret=epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&evt);
if(ret<0){error(1,errno,"epoll_ctl(add) connfd");}
}
//不是连接事件--> 读写事件-->有消息
else {
sockfd=ep[i].data.fd;
int nByte=read(sockfd,buff,sizeof(buff));
//缓冲区空,即将断开
if(nByte==0){
ret=epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL);
if(ret<0){error(1,errno,"epoll_ctl(delete)");}
close(sockfd);
cout<<"client ["<<sockfd<<"] closed connecttion"<<endl;
}
//连接异常
else if(nByte<0){
perror("epoll_wait error");
ret=epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL);
if(ret<0){error(1,errno,"epoll_ctl(delete)");}
close(sockfd);
}
//正常通信
else{
for(int j=0;j<nByte;++j){
buff[j]=toupper(buff[j]);//a->A
}
write(sockfd,buff,nByte);
write(STDOUT_FILENO,buff,nByte);
}
}
}
}
close(listenfd);
close(connfd);
return 0;
}
标签:std,SOCKET,epoll,int,listenfd,seraddr,0915,using,include
From: https://blog.csdn.net/qq_51583806/article/details/142371169