TCP服务器的几种实现方式
2018-03-05 14:30
302 查看
1.简介
2.TCP客户端
#include <iostream> #include <sys/socket.h> #include <arpa/inet.h> #include <cstdlib> #include <cstdio> #include <cstring> #include <unistd.h> using namespace std; int main() { //Create a socket For client to use TCP connect the Server int fd = socket(AF_INET,SOCK_STREAM,0); if(fd == -1) { perror("Cannot Create a socket for TCP"); exit(EXIT_FAILURE); } //Set the client IP address and port struct sockaddr_in client_addr; client_addr.sin_family = AF_INET; client_addr.sin_port = htons(0); client_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); memset(client_addr.sin_zero,0,8); //Bind the socket with IP address and port if(bind(fd,reinterpret_cast<sockaddr *>(&client_addr),sizeof(client_addr)) == -1) { perror("Cannot bind the socket"); exit(EXIT_FAILURE); } //Set the Server IP address and port struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(23333); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); memset(server_addr.sin_zero,0,8); //Try to Connect the server if(connect(fd,reinterpret_cast<sockaddr *>(&server_addr),sizeof(server_addr)) == -1) { perror("Cannot connect the server"); exit(EXIT_FAILURE); } while(true) { string buf; cin >> buf; if(buf == "stop") break; if(write(fd,buf.c_str(),buf.length()) != buf.length()) { perror("Something Wrong when write"); exit(EXIT_FAILURE); } } close(fd); }
3. TCP服务器
#include <iostream> #include <set> #include <cstdio> #include <cstdlib> #include <cstring> #include <arpa/inet.h> #include <sys/socket.h> #include <unistd.h> #include <sys/select.h> #include <sys/time.h> #include <sys/epoll.h> using namespace std; int main() { //Create the server listen socket int listen_fd = socket(AF_INET,SOCK_STREAM,0); if(listen_fd == -1) { perror("Cannot Create a Socket For TCP"); exit(EXIT_FAILURE); } //Set the Server IP Address and port struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(23333); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); memset(server_addr.sin_zero,0,8); //Set the socket option with reuse address,Otherwise we cannot bind immediately after reboot int is_reuse = 1; if(setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&is_reuse,sizeof(int)) == -1) { perror("Cannot Set socket option"); exit(EXIT_FAILURE); } // //Bind the socket with IP address and port if(bind(listen_fd,reinterpret_cast<sockaddr *>(&server_addr),sizeof(server_addr)) == -1) { perror("Cannot Bind the socket"); exit(EXIT_FAILURE); } //Start to listen in this socket if(listen(listen_fd,5) == -1) { perror("Cannot use the socket to listen"); exit(EXIT_FAILURE); } //Save the connected client information struct sockaddr_in client_addr; socklen_t length = sizeof(client_addr); //Server1:serial way,blocked IO,Interact with one client per time // while(true) { // char buf[1024]; // int connect_fd; // if((connect_fd = accept(listen_fd,reinterpret_cast<sockaddr *>(&client_addr),&length)) == -1) { // perror("Cannot get a TCP connection"); // continue; // } // int n; // while(n = read(connect_fd,buf,1024)) { // if(n == -1) { // perror("Error when read Data:"); // break; // } else { // memset(buf+n,0,1024-n); // char addr_ip[INET_ADDRSTRLEN]; // inet_ntop(AF_INET,&client_addr.sin_addr,addr_ip,sizeof(addr_ip)); // fprintf(stderr, "Receive data from:%s:%d,%s\n", addr_ip,ntohs(client_addr.sin_port),buf); // } // } // } // close(listen_fd); //Server2:serial,IO multiplexing with select,per second to choose an active socket to handle // fd_set read_fds; // FD_ZERO(&read_fds); // set<int> all_fd; // all_fd.insert(listen_fd); // while(true) { // struct timeval timeout = {1,0}; //select would change timeout value each time,we should reset it. // for(auto it = all_fd.begin();it != all_fd.end();it++) { //select would change timeout value each time, we should reset it too. // FD_SET(*it,&read_fds); // } // int result = select(*(all_fd.rbegin())+1,&read_fds,NULL,NULL,&timeout); //Blocked here until timeout or some socket can read // if(result == -1) { // perror("IO Error:"); // continue; // } else if(result == 0) { // continue; // } // if(FD_ISSET(listen_fd,&read_fds)) { // int connect_fd; // if((connect_fd = accept(listen_fd,reinterpret_cast<sockaddr *>(&client_addr),&length)) == -1) { //would not block now,because it is ready. // perror("Cannot get a TCP connection"); // continue; // } // char addr_ip[INET_ADDRSTRLEN]; // inet_ntop(AF_INET,&client_addr.sin_addr,addr_ip,sizeof(addr_ip)); // printf("Client %s:%d has connected to server\n",addr_ip,ntohs(client_addr.sin_port)); // FD_SET(connect_fd,&read_fds); //Add the new connect_fd monitored by select // all_fd.insert(connect_fd); // FD_CLR(connect_fd,&read_fds); //Clear the new connect_fd // FD_CLR(listen_fd,&read_fds); //Clear the listen_fd after handle it // } // char buf[1024]; // for(auto it = all_fd.begin();it != all_fd.end();++it) { // if(FD_ISSET(*it,&read_fds)) { // int n = read(*it,buf,1024); // char addr_ip[INET_ADDRSTRLEN]; // getpeername(*it,reinterpret_cast<sockaddr *>(&client_addr),&length); //Get the peer address by fd // inet_ntop(AF_INET,&client_addr.sin_addr,addr_ip,sizeof(addr_ip)); // if(n == -1 || n == 0) { // if(n == -1) // perror("Error when read Data:"); // else // printf("Client %s:%d has closed the connection\n",addr_ip,ntohs(client_addr.sin_port)); // close(*it); // all_fd.erase(it); // } else { // memset(buf+n,0,1024-n); // fprintf(stderr, "Receive data from:%s:%d,%s\n", addr_ip,ntohs(client_addr.sin_port),buf); // } // FD_CLR(*it,&read_fds); // } // } // } // close(listen_fd); //server3:serial,IO multiplexing with epoll(More effective way),per second to choose an active socket to handle int epoll_fd = epoll_create(1); //size is ignored in new version,simply set one positve interger is ok if(epoll_fd == -1) { perror("Cannot create epoll instance"); exit(EXIT_FAILURE); } int max_events = 20; struct epoll_event listen_event; struct epoll_event event_list[20]; listen_event.data.fd = listen_fd; listen_event.events = EPOLLIN|EPOLLET; //Set the level triggered mode, //If listenfd is ready,listen_event will be in event_list,we can check event_list to see either someone.data.fd is listen_fd. if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,listen_fd,&listen_event) == -1) { perror("Cannot add listen fd:"); exit(EXIT_FAILURE); } while(true) { int result = epoll_wait(epoll_fd,event_list,max_events,1000); if(result == -1) { perror("IO Error:"); continue; } else if(result == 0) { continue; } char buf[1024]; for(int i = 0;i < result;i++) { //The ready fds is in events[0,result).data.fd if(listen_fd == event_list[i].data.fd) { int connect_fd = accept(listen_fd,reinterpret_cast<sockaddr *>(&client_addr),&length); if(connect_fd == -1) { perror("Cannot get a TCP connection"); continue; } char addr_ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET,&client_addr.sin_addr,addr_ip,sizeof(addr_ip)); printf("Client %s:%d has connected to server\n",addr_ip,ntohs(client_addr.sin_port)); struct epoll_event read_event; //May debug here read_event.data.fd = connect_fd; read_event.events = EPOLLIN|EPOLLET; epoll_ctl(epoll_fd,EPOLL_CTL_ADD,connect_fd,&read_event); } else { int connect_fd = event_list[i].data.fd; int n = read(connect_fd,buf,1024); getpeername(connect_fd,reinterpret_cast<sockaddr *>(&client_addr),&length); //Get the peer address by fd char addr_ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET,&client_addr.sin_addr,addr_ip,sizeof(addr_ip)); //Change the IP address into char * if(n == -1 || n == 0) { if(n == -1) { perror("Error when read data"); } else { printf("Client %s:%d has closed the connection\n",addr_ip,ntohs(client_addr.sin_port)); } epoll_ctl(epoll_fd,EPOLL_CTL_DEL,connect_fd,NULL); close(connect_fd); continue; } memset(buf+n,0,1024-n); printf("Receive data from %s:%d,%s\n", addr_ip,ntohs(client_addr.sin_port),buf); } } } }
相关文章推荐
- TCP并发服务器的几种实现
- 协程写作方式实现的单进程 单线程 多协程的http(其实是tcp啦)服务器,实测性能和workerman相差不远(当然稳定性没法比), 基本每行代码都有中文注释~~呲牙呲牙呲牙 没办法用作生产环境
- Linux下两种TCP网络服务器实现方式:循环服务&并发服务
- Linux下两种TCP网络服务器实现方式:循环服务&并发服务
- tcp服务器被攻击的几种方式
- 不同页面之间实现参数传递的几种方式
- java实现文件以及文件夹拷贝的几种方式
- js实现页面跳转的几种方式
- Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)
- Android高仿qq及微信底部菜单的几种实现方式
- Unity中实现全局管理类的几种方式
- C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信 (服务器实现)
- JavaScript实现页面跳转的几种常用方式
- js实现几秒页面跳转的几种方式
- 用Jsp来实现文件下载功能的几种方式
- Qt中利用TCP实现多个客户端之间相互发送消息系以及服务器的群发信息
- js实现页面跳转的几种方式
- 详解Android 进程间通信的几种实现方式
- js实现页面跳转的几种方式
- TCP方式实现一个简单的RPC