keep_simple

导航

简易tcp服务器

server:

View Code
  1 #include <stdlib.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <sys/socket.h>
  5 #include <sys/epoll.h>
  6 #include <netinet/in.h>
  7 #include <arpa/inet.h>
  8 #include <fcntl.h>
  9 #include <unistd.h>
 10 #include <stdio.h>
 11 #include <errno.h>
 12 
 13 using namespace std;
 14 
 15 typedef struct ServerConfig
 16 {
 17     ServerConfig():domain_(AF_INET),
 18                  type_(SOCK_STREAM),
 19                  protocol_(0),
 20                  sin_family_(AF_INET),
 21                  sin_addr_("0.0.0.0"),
 22                  sin_port_(5555),
 23                  backlog_(20),
 24                  epollFdMaxNum_(256),
 25                  eventsMaxNum_(20),
 26                  epollTimeOut_(-1)
 27                  {}
 28 public:
 29    //socket 参数
 30    int domain_;
 31    int type_;
 32    int protocol_;
 33 
 34    //bind 地址使用
 35    int sin_family_;
 36    std::string sin_addr_;
 37    int sin_port_;
 38 
 39    //listen 参数
 40    int backlog_;
 41 
 42    //epoll 参数
 43    int epollFdMaxNum_;
 44    int eventsMaxNum_;
 45 
 46    int epollTimeOut_;
 47 }ServerConfig;
 48 
 49 class TestServer
 50 {
 51 public:
 52     TestServer():socketFd_(-1),
 53                  epollCreateFd_(-1),
 54                  pEvents_(NULL),
 55                  epollWaitRetNum_(-1),
 56                  addrLen_(sizeof(struct sockaddr_in)),
 57                  acceptFd_(-1),
 58                  readNum_(-1)
 59     {
 60         pEvents_= new struct epoll_event[config_.eventsMaxNum_];
 61         memset(&clientAddr_, 0, sizeof(struct sockaddr_in)); 
 62     }
 63     ~TestServer()
 64     {
 65         if(pEvents_!= NULL)
 66         {
 67             delete[] pEvents_;
 68         }
 69     }
 70 
 71     void init()
 72     {
 73         epollCreate();
 74         socket();
 75         bind();
 76         listen();
 77     }
 78     void startServer()
 79     {
 80         int sockfd = -1;
 81         int n = 0;
 82         for( ; ; )  
 83         {
 84             epollWaitRetNum_ = ::epoll_wait(epollCreateFd_, pEvents_, config_.eventsMaxNum_, config_.epollTimeOut_);
 85             for(int i=0;i<epollWaitRetNum_;++i)
 86             {
 87                 if(pEvents_[i].data.fd==socketFd_)
 88                 {
 89                     acceptFd_= ::accept(socketFd_,(struct sockaddr *)&clientAddr_, &addrLen_);
 90                     if(acceptFd_ <= 0)
 91                     {
 92                         std::cerr<<__LINE__<<":: accept error: "<< ::strerror(errno);
 93                         exit(1);
 94                     }
 95                     //setNonblocking(acceptFd_);
 96                     std::cout << "accapt a connection from: " << ::inet_ntoa(clientAddr_.sin_addr)<< std::endl;
 97 
 98                     event_.data.fd = acceptFd_;
 99                     event_.events = EPOLLIN|EPOLLET;
100                     epollCtl(epollCreateFd_, EPOLL_CTL_ADD, acceptFd_, &event_);
101                     continue;
102                 }
103                 if(pEvents_[i].events & EPOLLIN)
104                 {
105                     int readNum_ = -1;//读什么回复什么
106                     sockfd = pEvents_[i].data.fd;
107                     if (sockfd < 0)
108                         continue;
109                     if ((n = ::read(sockfd, &readNum_, sizeof(readNum_))) < 0) 
110                     {
111                         if (errno == ECONNRESET) 
112                         {
113                             close(sockfd);
114                             pEvents_[i].data.fd = -1;
115                         }
116                         else
117                         {
118                             std::cerr<<__LINE__<<":: read error: "<< ::strerror(errno);
119                         }
120                         continue;
121                     } 
122                     if (n == 0) 
123                     {
124                         close(sockfd);
125                         pEvents_[i].data.fd = -1;
126                         continue;
127                     }
128                     cout << "readNum: " << readNum_<< endl;
129                     ::write(sockfd, &(readNum_), sizeof(readNum_));
130 
131                     //event_.data.fd = sockfd;
132                     //event_.events = EPOLLIN|EPOLLET;
133                     //epollCtl(epollCreateFd_, EPOLL_CTL_MOD, sockfd, &event_);
134                     continue;
135                 }
136                 if(pEvents_[i].events & EPOLLOUT)
137                 {
138                     sockfd = pEvents_[i].data.fd;
139                     ::write(sockfd, &(readNum_), sizeof(readNum_));
140 
141                     event_.data.fd = sockfd;
142                     event_.events = EPOLLIN|EPOLLET;
143                     epollCtl(epollCreateFd_, EPOLL_CTL_MOD, sockfd, &event_);
144                 }
145             }
146         }
147 
148     }
149 private:
150     void socket()
151     {
152         socketFd_ = ::socket(config_.domain_, config_.type_, config_.protocol_);
153         if(-1 == socketFd_)
154         {
155             std::cerr<<__LINE__<<":: Create socket error: "<< ::strerror(errno);
156             exit(1);
157         }
158     }
159     void bind()
160     {
161         struct sockaddr_in serverAddr;
162         bzero(&serverAddr, sizeof(serverAddr));
163         serverAddr.sin_family = config_.sin_family_;
164         inet_aton(config_.sin_addr_.c_str(),&(serverAddr.sin_addr));//htons(portnumber);
165         serverAddr.sin_port=htons(config_.sin_port_);
166 
167         if(-1 == ::bind(socketFd_,(sockaddr *)&serverAddr, sizeof(serverAddr)))
168         {
169             std::cerr<<__LINE__<<":: Bind socket error: "<< ::strerror(errno);
170             exit(1);
171         }
172     }
173     void listen()
174     {
175         if(-1 == ::listen(socketFd_, config_.backlog_))
176         {
177             std::cerr<<__LINE__<<":: Listen socket error: "<< ::strerror(errno);
178             exit(1);
179         }
180 
181         event_.data.fd = socketFd_;
182         event_.events = EPOLLIN|EPOLLET;
183         epollCtl(epollCreateFd_, EPOLL_CTL_ADD, socketFd_, &event_);
184     }
185     void epollCreate()
186     {
187         epollCreateFd_ = ::epoll_create(config_.epollFdMaxNum_);
188         if(epollCreateFd_ < 0)
189         {
190             std::cerr<<__LINE__<<":: Epoll create error: "<< ::strerror(errno);
191             exit(1);
192         }
193     }
194     void epollCtl(int epfd, int op, int fd, struct epoll_event *ev)
195     {
196         if(-1 == epoll_ctl(epfd, op, fd, ev))
197         {
198             std::cerr<<__LINE__<<":: epoll_ctl error: "<< ::strerror(errno);
199             exit(0);
200         }
201     }
202     void setNonblocking(int sock)
203     {
204         int opts = fcntl(sock,F_GETFL);
205         if(opts<0)
206         {
207             std::cerr<<__LINE__<<":: fcntl error: "<< ::strerror(errno);
208             exit(1);
209         }
210         opts = opts|O_NONBLOCK;
211         if(fcntl(sock,F_SETFL,opts)<0)
212         {
213             std::cerr<<__LINE__<<":: fcntl error: "<< ::strerror(errno);
214             exit(1);
215         }
216     }
217 private:
218     int socketFd_;
219     int epollCreateFd_;
220     ServerConfig config_;
221 
222     struct epoll_event event_;
223     struct epoll_event *pEvents_;
224 
225     int epollWaitRetNum_;
226 
227     struct sockaddr_in clientAddr_;
228     socklen_t addrLen_;
229     int acceptFd_;
230 
231     int readNum_;
232 };
233 
234 int main(int argc, char* argv[])
235 {
236     TestServer ts;
237     ts.init();
238     ts.startServer();
239 }

client:

View Code
  1 #include <iostream>
  2 #include <stdlib.h> 
  3 #include <stdio.h> 
  4 #include <errno.h> 
  5 #include <string.h> 
  6 #include <netdb.h> 
  7 #include <sys/types.h> 
  8 #include <netinet/in.h> 
  9 #include <sys/socket.h> 
 10 #include <arpa/inet.h>
 11 #include <unistd.h>
 12 #include <fcntl.h>
 13 #include <error.h>
 14 #include <pthread.h>
 15 
 16 typedef struct ClientConfig
 17 {
 18     ClientConfig():domain_(AF_INET),
 19                  type_(SOCK_STREAM),
 20                  protocol_(0),
 21                  sin_family_(AF_INET),
 22                  sin_addr_("0.0.0.0"),
 23                  sin_port_(5555)
 24                  {}
 25 public:
 26    //socket 参数
 27    int domain_;
 28    int type_;
 29    int protocol_;
 30 
 31    //connect 地址使用
 32    int sin_family_;
 33    std::string sin_addr_;
 34    int sin_port_;
 35 }ClientConfig;
 36 
 37 class TestClient
 38 {
 39 public:
 40     TestClient(int n=0):socketFd_(-1),
 41                  sendNum_(0)
 42     {
 43         sendNum_ = n;
 44     }
 45     ~TestClient()
 46     {
 47         close();
 48     }
 49     void init()
 50     {
 51         socket();
 52         connect();
 53     }
 54     void startClient()
 55     {
 56         write();
 57         read();
 58     }
 59 private:
 60     void socket()
 61     {
 62         socketFd_ = ::socket(config_.domain_, config_.type_, config_.protocol_);
 63         if(-1 == socketFd_)
 64         {
 65             std::cerr<<__LINE__<<":: Create socket error: "<< ::strerror(errno)<<std::endl;
 66             exit(1);
 67         }
 68     }
 69     void connect()
 70     {
 71         serverAddr_.sin_family = config_.sin_family_;        
 72         serverAddr_.sin_port = htons(config_.sin_port_); 
 73         ::inet_aton(config_.sin_addr_.c_str(), &serverAddr_.sin_addr);
 74 
 75         int ret = ::connect(socketFd_, (struct sockaddr *)(&serverAddr_), sizeof(struct sockaddr));
 76         if(ret == -1) 
 77         { 
 78             std::cerr<<__LINE__<<":: connect error: "<< ::strerror(errno)<<std::endl;
 79             exit(1); 
 80         } 
 81     }
 82     void write()
 83     {
 84         int ret = ::write(socketFd_, &sendNum_, sizeof(int));
 85         if(ret < 0)
 86         {
 87             std::cerr<<__LINE__<<":: write error: "<< ::strerror(errno)<<std::endl;
 88             exit(1); 
 89         }
 90         std::cout<< "write Num : "<< sendNum_ <<std::endl;
 91     }
 92     void read()
 93     {
 94         int ret = ::read(socketFd_, &sendNum_, sizeof(int));
 95         if(ret < 0)
 96         {
 97             std::cout<<"write error: "<< ::strerror(errno)<<std::endl <<std::endl;
 98             exit(1);
 99         }
100         std::cout<<"readNum: "<< sendNum_<<std::endl;
101     }
102     void close()
103     {
104         int ret = ::close(socketFd_);
105         if(ret < 0)
106         {
107             std::cout<<"close error: "<< ::strerror(errno)<<std::endl <<std::endl;
108             exit(1);
109         }
110 
111     }
112     void setNonblocking(int sock)
113     {
114         int opts = fcntl(sock,F_GETFL);
115         if(opts<0)
116         {
117             std::cerr<<__LINE__<<":: fcntl error: "<< ::strerror(errno)<<std::endl;
118             exit(1);
119         }
120         opts = opts|O_NONBLOCK;
121         if(fcntl(sock,F_SETFL,opts)<0)
122         {
123             std::cerr<<__LINE__<<":: fcntl error: "<< ::strerror(errno)<<std::endl;
124             exit(1);
125         }
126     }
127 private:
128     int socketFd_;
129     ClientConfig config_;
130 
131     struct sockaddr_in serverAddr_;
132 
133     int sendNum_;
134     
135 };
136 
137 void* example(void * arg)
138 {
139     TestClient* pTC = static_cast<TestClient*>(arg);
140     pTC->init();
141     for(int i=0; i<1000; ++i)
142     {
143         pTC->startClient();
144         //usleep(10*1000);
145     }
146 
147     delete pTC;
148     return 0;
149 }
150 int main(int argc, char* argv[])
151 {
152     int const threadNum = 100;
153     pthread_t pid[threadNum] = {0};
154 
155     int ret = -1;
156     for(int i =0; i<threadNum; ++i)
157     {
158         TestClient *pTC = new TestClient(i);
159         ret = pthread_create(&pid[i], NULL, example, pTC);
160         if(ret != 0)
161         {
162             std::cerr<<__LINE__<<":: Create thread error: "<< ::strerror(errno)<<std::endl;
163             exit(1);
164         }
165     }
166 
167     for(int j=0; j<threadNum; ++j)
168     {
169         pthread_join(pid[j], NULL);
170     }
171 }

 

posted on 2013-04-28 14:42  keep_simple  阅读(331)  评论(0)    收藏  举报