linux下c/c++实例之socket服务器实例
生活随笔
收集整理的這篇文章主要介紹了
linux下c/c++实例之socket服务器实例
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、簡(jiǎn)介
?
二、詳解
簡(jiǎn)單socket服務(wù)器和客戶端(基礎(chǔ))
服務(wù)器:
/* * socket簡(jiǎn)單編程 服務(wù)端*/#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h>#define BUFFSIZE 1024int main(int argc, char *argv[]) {int server_sockfd = 0;int client_sockfd = 0;int len = 0;int sin_size = 0;struct sockaddr_in server_addr;struct sockaddr_in client_addr;char buf[BUFFSIZE] = {0};bzero(&server_addr, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(8000);if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket error!\n");return -1;}if(bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0){perror("bind error!\n");return -1;}if(listen(server_sockfd, 5) < 0){perror("listen error!\n");return -1;}sin_size= sizeof(struct sockaddr_in);if((client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &sin_size)) < 0){perror("accept error!\n");return -1;}printf("accept client %s\n",inet_ntoa(client_addr.sin_addr));len = send(client_sockfd, "Hello word!\n",30,0);while((len = recv(client_sockfd, buf, BUFFSIZE, 0)) >0){buf[len] = '\0';printf("buf = %s\n",buf);if(send(client_sockfd, buf, len, 0) < 0){perror("send error!\n");return -1;}}close(client_sockfd);close(server_sockfd);return 0; }?客戶端:
/* * socket簡(jiǎn)單編程 客戶端*/#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h>#define BUFFSIZE 1024int main(int argc, char *argv[]) {int client_sockfd = 0;int len = 0;struct sockaddr_in server_addr;char buf[BUFFSIZE] = {0};bzero(&server_addr, sizeof(struct sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");server_addr.sin_port = htons(8000);if((client_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket error!\n");return -1;}if(connect(client_sockfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) < 0){perror("client error!\n");return -1;}printf("connect success!\n");len = recv(client_sockfd, buf, BUFFSIZE, 0);buf[len] = '\0';printf("client_buf = %s\n",buf);while(1){printf("Enter string to send:");scanf("%s",buf);if(!strcmp(buf,"quit")){break;}len = send(client_sockfd, buf, strlen(buf), 0);len = recv(client_sockfd, buf, BUFFSIZE, 0);buf[len] = '\0';printf("received: %s\n",buf);}close(client_sockfd);return 0; }?
(1)多線程并發(fā)服務(wù)器server.c
//使用pthread線程庫(kù) #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> #include <stdlib.h> #define PORT 1234 //服務(wù)器端口 #define BACKLOG 5 //listen隊(duì)列等待的連接數(shù) #define MAXDATASIZE 1024 //緩沖區(qū)大小void process_cli(int connectfd, struct sockaddr_in client); //客戶端請(qǐng)求處理函數(shù) void* start_routine(void* arg); //線程函數(shù)typedef struct _ARG {int connfd;struct sockaddr_in client; }ARG; //客戶端結(jié)構(gòu)體void main() {int listenfd, connectfd; //socket描述符pthread_t thread; //線程體變量ARG *arg; //客戶端結(jié)構(gòu)體變量struct sockaddr_in server; //服務(wù)器地址信息結(jié)構(gòu)體struct sockaddr_in client; //客戶端地址信息結(jié)構(gòu)體int sin_size;if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { //調(diào)用socket,創(chuàng)建監(jiān)聽(tīng)客戶端的socketperror("Creating socket failed.");exit(1);}int opt = SO_REUSEADDR; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //設(shè)置socket屬性,端口可以重用//初始化服務(wù)器地址結(jié)構(gòu)體bzero(&server,sizeof(server));server.sin_family=AF_INET;server.sin_port=htons(PORT);server.sin_addr.s_addr = htonl (INADDR_ANY);if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) { //調(diào)用bind,綁定地址和端口perror("Bind error.");exit(1);} if(listen(listenfd,BACKLOG) == -1){ //調(diào)用listen,開(kāi)始監(jiān)聽(tīng)perror("listen() error\n");exit(1);}sin_size=sizeof(struct sockaddr_in);while(1) {if ((connectfd = accept(listenfd,(struct sockaddr *)&client,(socklen_t *)&sin_size))==-1) { //調(diào)用accept,返回與服務(wù)器連接的客戶端描述符perror("accept() error\n");exit(1);}arg = new ARG;arg->connfd = connectfd;memcpy(&arg->client, &client, sizeof(client));if (pthread_create(&thread, NULL, start_routine, (void*)arg)) { //創(chuàng)建線程,以客戶端連接為參數(shù),start_routine為線程執(zhí)行函數(shù)perror("Pthread_create() error");exit(1);}}close(listenfd); //關(guān)閉監(jiān)聽(tīng)socket }void process_cli(int connectfd, sockaddr_in client) {int num;char recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], cli_name[MAXDATASIZE];printf("You got a connection from %s. ",inet_ntoa(client.sin_addr) );num = recv(connectfd, cli_name, MAXDATASIZE,0);if (num == 0) {close(connectfd);printf("Client disconnected.\n");return;}cli_name[num - 1] = '\0';printf("Client's name is %s.\n",cli_name);while (num = recv(connectfd, recvbuf, MAXDATASIZE,0)) {recvbuf[num] = '\0';printf("Received client( %s ) message: %s",cli_name, recvbuf);for (int i = 0; i < num - 1; i++) {sendbuf[i] = recvbuf[num - i -2];}sendbuf[num - 1] = '\0';send(connectfd,sendbuf,strlen(sendbuf),0);}close(connectfd); } void* start_routine(void* arg) {ARG *info;info = (ARG *)arg;process_cli(info->connfd, info->client);delete info;pthread_exit(NULL); }客戶端:
#include <iostream>using namespace std; string m_strIP = "172.168.1.242"; int m_nPort = 15003;void main() {int fd;int retcode;int recv_count;char *rcvbuf;struct sockaddr_in addr;struct timeval timeo = {10, 0};unsigned long flags;memset(&addr,0x00,sizeof(struct sockaddr_in));fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr(m_strIP);addr.sin_port = htons(m_nPort);//flags = fcntl(fd, F_GETFL, 0);//fcntl(fd, F_SETFL, flags | O_NONBLOCK);retcode = connect(fd, (struct sockaddr*)&addr, sizeof(addr));recv_count = recv(fd, rcvbuf, 26, 0);cout<<recv_count<<endl;cout<<rcvbuf<<endlif(0 == retcode){ if (fcntl(fd, F_SETFL, flags) < 0){ cout<<"Connect error!"<<endl;return -1;}else{cout<<"Connect ok sockfd!"<<endl;return fd;}} }(2)select非阻塞服務(wù)器
select單線程服務(wù)器:
select多線程服務(wù)器:
select服務(wù)器:
socket_server.h(頭文件):
socket_server.cpp:
#include "socket_server.h" #include <pthread.h> #include <sys/time.h> #include <sys/select.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <fcntl.h>socket_server::socket_server() {memset(sock_array, 0, sizeof(sock_array));nSock = 0; }socket_server::~socket_server() { }void *sock_thread_proc(void *arg) {pthread_detach(pthread_self());socket_server *p_sock = (socket_server *)arg;p_sock->sock_thread();return ((void *)0); }void *socket_server::sock_thread() {struct timeval tv;//gettimeofday(&tv, NULL);tv.tv_sec=10; // select超時(shí)時(shí)間tv.tv_usec=0; fd_set readfds;fd_set writefds;FD_ZERO(&readfds);FD_ZERO(&writefds);int nRet;int ret;int i,j;char recv_buf[128] = {0};while(1) { if (nSock == 0) {sleep(4);cout<<"nsock is zero"<<endl;continue;}maxfd = sock_array[0];FD_SET(sock_array[0], &readfds);for (i = 1; i< nSock; i++) {FD_SET(sock_array[i], &readfds);if (sock_array[i] > maxfd)maxfd = sock_array[i];}cout<<"maxfd:"<<maxfd<<endl;nRet=select(maxfd + 1, &readfds, NULL, NULL, &tv);if(nRet>0) {for (i = 0; i < nSock; i++) {if (FD_ISSET(sock_array[i], &readfds)) {if ((ret = recv(sock_array[i], recv_buf, sizeof(recv_buf), 0)) < 0)my_err("recv", __FUNCTION__, __LINE__);if (ret > 0) {recv_buf[ret] = '\0';cout<<"server接受數(shù)據(jù):"<<recv_buf<<endl;}elsecout<<"server無(wú)數(shù)據(jù)。"<<endl;FD_SET(sock_array[i], &writefds);nRet=select(sock_array[i] + 1, NULL, &writefds, NULL, &tv);if(nRet > 0) {if (FD_ISSET(sock_array[i], &writefds)) {char *send_data = "接受數(shù)據(jù)成功!";if (send(sock_array[i], send_data, strlen(send_data), 0) < 0){my_err("send", __FUNCTION__, __LINE__);}cout<<"send succeed"<<endl;}}elsecout<<"發(fā)送超時(shí)!"<<endl;//關(guān)閉該套接字close(sock_array[i]);for (j = i; j < nSock - 1; j++) {sock_array[j] = sock_array[j + 1];}nSock--;}}}else {cout<<"接收超時(shí)!"<<endl;break;}cout<<"******deal sock finish******"<<endl;}return ((void *)0); } void socket_server::my_err(const char*err_string, char *function, int line) {fprintf(stderr, "func[%s]line:%d\n", function, line);perror(err_string);exit(1); } void socket_server::socket_op() {pthread_t pid;pthread_create(&pid, NULL, sock_thread_proc, this);int sock_fd;int new_sockfd;struct sockaddr_in serv_addr;struct sockaddr_in client_addr;int nRet;int i;sock_fd = socket(AF_INET, SOCK_STREAM, 0);if (sock_fd < 0)my_err("socket", __FUNCTION__, __LINE__);fcntl(sock_fd, F_SETFL, O_NONBLOCK); //設(shè)置socket非阻塞int optval = 1;//可以重新綁定端口if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) < 0)my_err("setsockopt", __FUNCTION__, __LINE__);memset(&serv_addr, 0, sizeof(struct sockaddr_in));serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(4507);serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);nRet = bind(sock_fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in));if (nRet < 0)my_err("bind", __FUNCTION__, __LINE__);nRet = listen(sock_fd, 10000);if (nRet < 0)my_err("listen", __FUNCTION__, __LINE__);fd_set readfds;FD_ZERO(&readfds);struct timeval tv;//gettimeofday(&tv, NULL);tv.tv_sec = 10; // select超時(shí)時(shí)間tv.tv_usec=0;socklen_t addr_len = sizeof(struct sockaddr_in);while(1) {FD_SET(sock_fd, &readfds);nRet=select(sock_fd + 1, &readfds, NULL, NULL, &tv);if(nRet > 0) {if (FD_ISSET(sock_fd, &readfds)) {new_sockfd = accept(sock_fd, (struct sockaddr*)&client_addr, &addr_len);sock_array[nSock++] = new_sockfd; //入數(shù)組}}else if(nRet == 0) {cout<<"waiting for connecting......"<<endl;continue;}else {cout<<"select error!"<<endl;}} } int main() {socket_server *obj = new socket_server();cout<<"******socket server begin to accept client******"<<endl;obj->socket_op();delete obj;return 0; }select客戶端:
socket_client.h(頭文件):
socket_client.cpp:
#include "socket_client.h" #include <pthread.h> #include <sys/time.h> #include <sys/select.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <fcntl.h> #include <arpa/inet.h>socket_client::socket_client() { }socket_client::~socket_client() { }void socket_client::my_err(const char*err_string, char *function, int line) {fprintf(stderr, "func[%s]line:%d\n", function, line);perror(err_string);exit(1); }void socket_client::socket_connect(const int conn_timeout) {int sock_fd;int nRet;struct sockaddr_in addr;fd_set rdset;fd_set wtset;int retval;char sndbuff[1024] = "socket connnect to the server succeed.";char recv_buf[1024] = {0};sock_fd = socket(AF_INET, SOCK_STREAM, 0);if (sock_fd < 0)my_err("socket", __FUNCTION__, __LINE__);addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr("127.0.0.1");addr.sin_port = htons(4507);if (fcntl(sock_fd, F_SETFL, fcntl(sock_fd, F_GETFL) | O_NONBLOCK) < 0) {my_err("fcntl", __FUNCTION__, __LINE__);}nRet = connect(sock_fd, (struct sockaddr*)&addr, sizeof(addr));if (nRet < 0) {my_err("fcntl", __FUNCTION__, __LINE__);}FD_ZERO(&wtset);FD_SET(sock_fd, &wtset);struct timeval tv;tv.tv_sec = conn_timeout; // select超時(shí)時(shí)間tv.tv_usec = 0;retval = select(sock_fd + 1, NULL, &wtset, NULL, &tv);if (retval == 0) {cout<<"send timeout......"<<endl;}else if (retval > 0) {if(FD_ISSET (sock_fd, &wtset)) {if (send(sock_fd, sndbuff, strlen(sndbuff), 0) < 0)my_err("send", __FUNCTION__, __LINE__);cout<<"send succeed!"<<endl;} } FD_ZERO(&rdset);FD_SET(sock_fd, &rdset);retval = select(sock_fd + 1, &rdset, NULL, NULL, &tv);if (retval == 0) {cout<<"recv timeout......"<<endl;}else if (retval > 0) {if(FD_ISSET (sock_fd, &rdset)) {if ((retval = recv(sock_fd, recv_buf, sizeof(recv_buf), 0)) < 0)my_err("recv", __FUNCTION__, __LINE__); recv_buf[retval] = '\0';cout<<"server接受數(shù)據(jù):"<<recv_buf<<endl;} } close(sock_fd); } int main() {socket_client *obj = new socket_client();obj->socket_connect(10);delete obj;return 0; }(3)pool非阻塞服務(wù)器和客戶端
pool服務(wù)器:
socket_server.h(頭文件):
socket_server.cpp:
#include "socket_server.h" #include <pthread.h> #include <sys/time.h> #include <sys/select.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <fcntl.h> #include <poll.h>socket_server::socket_server() {pthread_mutex_init(&m_mutex, NULL);pthread_mutex_init(&m_lock, NULL);pthread_cond_init(&c_lock, NULL);memset(sock_array, 0, sizeof(sock_array));nSock = 0; }socket_server::~socket_server() {pthread_mutex_destroy(&m_mutex);pthread_mutex_destroy(&m_lock);pthread_cond_destroy(&c_lock); }void *sock_thread_proc(void *arg) {pthread_detach(pthread_self());socket_server *p_sock = (socket_server *)arg;p_sock->sock_thread();return ((void *)0); } void *sock_recvsend_proc(void *arg) {pthread_detach(pthread_self());thread_param *p_arg = (thread_param *)arg;socket_server *p_sock = (socket_server *)p_arg->t_this;p_sock->sock_recvsend(p_arg->sockd);delete p_arg;return ((void *)0); } void socket_server::sock_recvsend(int sockfd) {char sndbuff[32767] = {0};int timeout = 10*1000;int ret;int nRet;int count;char recv_buf[32767] = {0};FILE *fp = fopen("./body.txt", "r+");fseek(fp, 0, SEEK_END);int len = ftell(fp);fseek(fp, 0, SEEK_SET);fread(sndbuff, 1, len, fp);while(1) {struct pollfd event;memset(&event, 0, sizeof(event));event.fd = sockfd;event.events = POLLIN;recv_continue:nRet = poll((struct pollfd*)&event, 1, timeout);if (nRet < 0) {printf("poll error!\n");exit(1); }else if (nRet > 0){ //有事件發(fā)生if (event.revents & POLLIN) {if ((ret = recv(event.fd, recv_buf, sizeof(recv_buf), 0)) < 0)my_err("recv", __FUNCTION__, __LINE__);if (ret == 0) {cout<<"out"<<endl;break;}cout<<"server接受數(shù)據(jù):"<<ret<<":"<<strlen(recv_buf)<<endl;recv_buf[ret] = '\0';if(strstr(recv_buf,"Envelope>") == NULL){goto recv_continue;}}memset(&event, 0, sizeof(event));event.fd = sockfd;event.events = POLLOUT;send_continue:nRet = poll((struct pollfd*)&event, 1, timeout);if (nRet > 0) {if (event.revents & POLLOUT) {if ((count = send(event.fd, sndbuff, strlen(sndbuff), 0)) < 0){my_err("send", __FUNCTION__, __LINE__);}cout<<"count:"<<count<<endl;if (count < len) {len = len - count;goto send_continue;} }}else {cout<<"發(fā)送超時(shí)!"<<endl;}}else if(nRet == 0) {cout<<"waiting for connecting123......"<<endl;continue;}else {cout<<"poll error!"<<endl;}}close(sockfd); } void *socket_server::sock_thread() {int timeout = 10*1000;int nRet;int i,j;while(1) { pthread_mutex_lock(&m_mutex);int num = nSock;pthread_mutex_unlock(&m_mutex);while (nSock == 0) {pthread_mutex_lock(&m_lock);pthread_cond_wait(&c_lock, &m_lock);pthread_mutex_unlock(&m_lock);}memset(fds, 0, sizeof(struct pollfd)*10000);for (i = 0; i < nSock; i++) {fds[i].fd = sock_array[i];fds[i].events = POLLIN;}nRet = poll(fds, nSock, timeout);if (nRet < 0) {printf("poll error!\n");exit(1); }else if (nRet > 0){ //有事件發(fā)生for (i = 0; i < nSock; i++) {if (fds[i].revents & POLLIN) {pthread_t pid;thread_param *param = new thread_param();param->t_this = this;param->sockd = fds[i].fd;pthread_create(&pid, NULL, sock_recvsend_proc, param);pthread_mutex_lock(&m_mutex);for (j = i; j < nSock - 1;j++) {sock_array[j] = sock_array[j + 1];}nSock--; pthread_mutex_unlock(&m_mutex);}}}else {cout<<"接收超時(shí)!"<<endl;break;}}return ((void *)0); } void socket_server::my_err(const char*err_string, char *function, int line) {fprintf(stderr, "func[%s]line:%d\n", function, line);perror(err_string);exit(1); } void socket_server::socket_op() {pthread_t pid;pthread_create(&pid, NULL, sock_thread_proc, this);int sock_fd;int new_sockfd;struct sockaddr_in serv_addr;struct sockaddr_in client_addr;int nRet;int i;sock_fd = socket(AF_INET, SOCK_STREAM, 0);if (sock_fd < 0)my_err("socket", __FUNCTION__, __LINE__);fcntl(sock_fd, F_SETFL, O_NONBLOCK); //設(shè)置socket非阻塞int optval = 1;//可以重新綁定端口if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) < 0)my_err("setsockopt", __FUNCTION__, __LINE__);memset(&serv_addr, 0, sizeof(struct sockaddr_in));serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(4507);serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);nRet = bind(sock_fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in));if (nRet < 0)my_err("bind", __FUNCTION__, __LINE__);nRet = listen(sock_fd, 10000);if (nRet < 0)my_err("listen", __FUNCTION__, __LINE__);int timeout = 5*1000;struct pollfd p_fds;socklen_t addr_len = sizeof(struct sockaddr_in);memset(&p_fds, 0, sizeof(p_fds));p_fds.fd = sock_fd;p_fds.events = POLLIN;while(1) {nRet = poll((struct pollfd*)&p_fds, 1, timeout);if(nRet > 0) {if (p_fds.revents & POLLIN) {new_sockfd = accept(sock_fd, (struct sockaddr*)&client_addr, &addr_len);pthread_mutex_lock(&m_mutex);sock_array[nSock++] = new_sockfd; //入數(shù)組pthread_cond_signal(&c_lock);pthread_mutex_unlock(&m_mutex);}}else if(nRet == 0) {cout<<"waiting for connecting......"<<endl;continue;}else {cout<<"poll error!"<<endl;}}close(sock_fd); } int main() {socket_server *obj = new socket_server();cout<<"******socket server begin to accept client******"<<endl;obj->socket_op();delete obj;return 0; }pool客戶端:
socket_client.h(頭文件):
socket_client.cpp:
#include "socket_client.h" #include <pthread.h> #include <sys/time.h> #include <sys/select.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <fcntl.h> #include <arpa/inet.h> #include <poll.h>socket_client::socket_client() { }socket_client::~socket_client() { }void socket_client::my_err(const char*err_string, char *function, int line) {fprintf(stderr, "func[%s]line:%d\n", function, line);perror(err_string);exit(1); }void socket_client::socket_connect(const int conn_timeout) {int sock_fd;int nRet;struct sockaddr_in addr;fd_set rdset;fd_set wtset;int retval;char sndbuff[81920] = {0};FILE *fp = fopen("./file.txt", "r+");fseek(fp, 0, SEEK_END);int len = ftell(fp);fseek(fp, 0, SEEK_SET);fread(sndbuff, 1, len, fp);//cout<<len<<":"<<strlen(sndbuff)<<endl;char recv_buf[81920] = {0};sock_fd = socket(AF_INET, SOCK_STREAM, 0);if (sock_fd < 0)my_err("socket", __FUNCTION__, __LINE__);//int nRecvBuf = 32 * 1024;//if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int)) < 0)// my_err("setsockopt", __FUNCTION__, __LINE__);addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr("172.168.1.242");addr.sin_port = htons(4507);nRet = connect(sock_fd, (struct sockaddr*)&addr, sizeof(addr));if (nRet < 0) {my_err("connect", __FUNCTION__, __LINE__);}if (fcntl(sock_fd, F_SETFL, fcntl(sock_fd, F_GETFL) | O_NONBLOCK) < 0) {my_err("fcntl", __FUNCTION__, __LINE__);}cout<<"sock_fd1:"<<sock_fd<<endl;for (int i = 0; i < 1000; i++){int timeout = 10*1000;struct pollfd event;int send_count = 0;memset(&event, 0, sizeof(event));event.fd = sock_fd;event.events = POLLOUT;send_again:retval = poll((struct polled*)&event, 1, timeout);if (retval == 0) {cout<<"send timeout......"<<endl;}else if (retval > 0) {if(event.revents & POLLOUT) {if ((send_count = send(event.fd, sndbuff, strlen(sndbuff), 0)) < 0)my_err("send", __FUNCTION__, __LINE__);cout<<"send succeed:"<<send_count<<endl;if (send_count < len) {len = len - send_count;goto send_again;} }} // while (1) {memset(&event, 0, sizeof(event));event.fd = sock_fd;event.events = POLLIN; retry: retval = poll((struct polled*)&event, 1, timeout);if (retval == 0) {cout<<"recv timeout......"<<endl;}else if (retval > 0) {if(event.revents & POLLIN) {memset(recv_buf, 0, sizeof(recv_buf));//cout<<"bein"<<endl;if ((retval = recv(event.fd, recv_buf, sizeof(recv_buf), 0)) < 0)my_err("recv", __FUNCTION__, __LINE__);if (retval == 0) {break;} recv_buf[retval] = '\0';cout<<"server接受數(shù)據(jù):"<<strlen(recv_buf)<<endl;//fwrite(recv_buf, 1, strlen(recv_buf), fd);if(strstr(recv_buf,"Envelope>")==NULL){//cout<<"server接受數(shù)據(jù):"<<strlen(recv_buf)<<":"<<recv_buf<<endl;goto retry;}// cout<<"server接受數(shù)據(jù):"<<strlen(recv_buf)<<":"<<recv_buf<<endl;} }//}} close(sock_fd); } int main() {socket_client *obj = new socket_client();struct timeval *t_start, *t_end;int timeuse;int i;t_start = new timeval();gettimeofday(t_start, NULL);for(i = 0; i < 1; i++)obj->socket_connect(10);t_end = new timeval();gettimeofday(t_end, NULL);timeuse = 1000000 * (t_end->tv_sec - t_start->tv_sec ) + t_end->tv_usec - t_start->tv_usec; printf("時(shí)間為(ms):%d, %d\n", timeuse,timeuse/1000);delete obj;delete t_start;delete t_end;return 0; }makefile:
CC=g++ CFLAGS=-g -DDEBUG LDFLAGS= LIBS= all: socket_client socket_serversocket_client: socket_client.cpp$(CC) -o $@ $(LDFLAGS) socket_client.cpp $(LIBS) socket_server: socket_server.cpp$(CC) -o $@ $(LDFLAGS) socket_server.cpp $(LIBS) clean:rm -rf *.o socket_client socket_server(4)epool非阻塞服務(wù)器和客戶端
epool服務(wù)器:
#include <stdio.h> #include <sys/epoll.h> #include <stdlib.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/resource.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <strings.h> #define MAXBUF 1024 #define MAXEPOLLSIZE 10000 int main(int argc, char *argv[]) {int listener, new_fd, kdpfd, nfds, n, ret, curfds;socklen_t len;struct sockaddr_in my_addr,their_addr;struct epoll_event ev;struct epoll_event pevent[MAXEPOLLSIZE];struct rlimit rt;rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;if (setrlimit(RLIMIT_NOFILE, &rt) == -1) {perror("setrlimit");exit(1);}else {printf("設(shè)置系統(tǒng)資源參數(shù)成功!\n");}if( (listener = socket( AF_INET, SOCK_STREAM, 0)) == -1) {perror("socket");exit(1);}else {printf("socket 創(chuàng)建成功!\n");}if (fcntl(listener, F_SETFL, fcntl(listener, F_GETFD, 0) | O_NONBLOCK) == -1) {perror("fcntl");return -1;}my_addr.sin_family = PF_INET;my_addr.sin_port = htons(5000);my_addr.sin_addr.s_addr = INADDR_ANY;if ( bind( listener, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -1 ) {perror("bind");exit(1);}else {printf("IP 地址和端口綁定成功\n");}if (listen(listener, 2) == -1) {perror("listen");exit(1);}else{printf("開(kāi)啟服務(wù)成功!\n");}kdpfd = epoll_create(MAXEPOLLSIZE);len = sizeof(struct sockaddr_in);ev.events = EPOLLIN | EPOLLET;ev.data.fd = listener;if( epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0 ) {fprintf( stderr, "epoll set insertion error: fd=%d\n", listener );return -1;}else {printf("監(jiān)聽(tīng) socket 加入 epoll 成功!\n");}curfds = 1;int timeout = 10*1000;while(1) {/* 等待有事件發(fā)生 */nfds = epoll_wait(kdpfd, pevent, curfds, timeout);if( nfds == -1 ) {perror("epoll_wait");break;}else if (nfds == 0) {printf("waiting for connecting...\n");continue;}for (n = 0; n < nfds; n++) {if (pevent[n].data.fd == listener) {new_fd = accept(listener, (struct sockaddr*)&their_addr, &len );if( new_fd < 0 ){perror("accept");continue;}else{printf("有連接來(lái)自于: %s:%d, 分配的 socket 為:%d\n",inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), new_fd);}if (fcntl(new_fd, F_SETFL, fcntl(new_fd, F_GETFD, 0) | O_NONBLOCK) == -1){perror("fcntl");return -1;}ev.events = EPOLLIN | EPOLLET;ev.data.fd = new_fd;if(epoll_ctl( kdpfd, EPOLL_CTL_ADD, new_fd, &ev) < 0) {fprintf(stderr, "把 socket '%d' 加入 epoll 失敗!%s\n",new_fd, strerror(errno));return -1;}curfds ++;}else if(pevent[n].events & EPOLLOUT){char buf[MAXBUF + 1];int len;bzero(buf, MAXBUF + 1);len = recv(pevent[n].data.fd, buf, MAXBUF, 0);if (len > 0){printf("%d接收消息成功:'%s',共%d個(gè)字節(jié)的數(shù)據(jù)\n", pevent[n].data.fd, buf, len);}else{if (len < 0)printf("消息接收失敗!錯(cuò)誤代碼是%d,錯(cuò)誤信息是'%s'/n", errno, strerror(errno));elseprintf("recv empty\n");close(pevent[n].data.fd);continue;}if (len ==0 && errno != 11) {epoll_ctl(kdpfd, EPOLL_CTL_DEL, pevent[n].data.fd,&ev);curfds--;}}}}close(listener);close(kdpfd);return 0; }epoll客戶端:
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/epoll.h> #include <stdlib.h> #include <sys/types.h> #include <netinet/in.h> #include <string.h> #define MAXEPOLLSIZE 10000 int main() {int sock_fd;struct sockaddr_in addr;struct epoll_event ev;struct epoll_event pevent[MAXEPOLLSIZE];int nRet;int count = 0;if( (sock_fd = socket( PF_INET, SOCK_STREAM, 0)) == -1) {perror("socket");exit(1);}addr.sin_family = PF_INET;addr.sin_addr.s_addr = inet_addr("127.0.0.1");addr.sin_port = htons(5000);nRet = connect(sock_fd, (struct sockaddr*)&addr, sizeof(addr));if (nRet < 0) {perror("connect");return -1;}if (fcntl(sock_fd, F_SETFL, fcntl(sock_fd, F_GETFD, 0) | O_NONBLOCK) == -1) {perror("fcntl");return -1;}int kdpfd = epoll_create(MAXEPOLLSIZE);int len = sizeof(struct sockaddr_in);ev.events = EPOLLOUT | EPOLLET;ev.data.fd = sock_fd;if( epoll_ctl(kdpfd, EPOLL_CTL_ADD, sock_fd, &ev) < 0 ) {fprintf( stderr, "epoll set insertion error: fd=%d\n", sock_fd);return -1;}int curfds = 1;int timeout = 10*1000;int nfds;while(1) {nfds = epoll_wait(kdpfd, pevent, curfds, timeout);if( nfds == -1 ) {perror("epoll_wait");break;}else if (nfds == 0) {printf("waiting for connecting...\n");continue;}int n;printf("nfds:%d\n", nfds);for (n = 0; n < nfds; n++) {if (pevent[n].evnets & EPOLLIN) {char send_buf[100] = "my name is aoyang";count = send(pevent[n].data.fd, send_buf, strlen(send_buf), 0);if (count != strlen(send_buf)) {printf("send error!\n");}printf("count:%d\n", count);epoll_ctl(kdpfd, EPOLL_CTL_DEL, pevent[n].data.fd,&ev);curfds--;close(pevent[n].data.fd);return 0;}}} }(5)其他設(shè)計(jì)
#include "user_exception.h" #include "tcpsocket.h"#if defined (MEM_DEBUG) #define new DEBUG_NEW #define delete DEBUG_DELETE #endifnamespace util { tcpsocket::tcpsocket(): ipsocket() {_runmode = -1; } tcpsocket::~tcpsocket() {close(); }//client use int tcpsocket::create(const char* ipaddr, int port) {::memset(&inet_address, 0, sizeof(inet_address));if (ipaddr == 0){inet_address.sin_addr.s_addr = htonl(INADDR_ANY);}else{ // if (::inet_pton(AF_INET, ipaddr, &inet_address.sin_addr) <= 0) // throw bad_file(__FILE__, __LINE__, bad_file::bad_sock, strerror(errno));inet_address.sin_addr.s_addr = inet_addr(ipaddr) ;}inet_address.sin_family = AF_INET;inet_address.sin_port = htons(port);_runmode = 0;open(TCP);connect(&inet_address);return 0; } //server use int tcpsocket::create(int port) {open(TCP);::memset(&inet_address, 0, sizeof(inet_address));inet_address.sin_family = AF_INET;inet_address.sin_addr.s_addr = htonl(INADDR_ANY);inet_address.sin_port = htons(port);bind(&inet_address);accept(&inet_address);_runmode = 1;return 0; } void tcpsocket::receive(string& msg) {int read_count;int total;int len;char buff[4];if (this == 0)return;// Read length.total = 0;do{read_count = recv(buff + total, 4 - total);if (read_count < 0){if (errno == EINTR)continue;elsethrow bad_file(__FILE__, __LINE__, bad_file::bad_sock, strerror(errno));}total += read_count;if (total == 0) // No data available.throw bad_file(__FILE__, __LINE__, bad_file::bad_sock, strerror(errno));} while (total < 4);// Get message length.len = ((buff[0] & 0xff) << 24) + ((buff[1] & 0xff) << 16) + ((buff[2] & 0xff) << 8) + (buff[3] & 0xff);if (len <= 0)throw bad_file(__FILE__, __LINE__, bad_file::bad_sock, strerror(errno));// Read message.char* data = new char[len + 1];total = 0;do{read_count = ipsocket::recv(data + total, len - total);if (read_count < 0){if (errno == EINTR){continue;}else{delete[] data;throw bad_file(__FILE__, __LINE__, bad_file::bad_sock, strerror(errno));}}total += read_count;} while (total < len);data[len] = '\0';msg = data;delete[] data; #if defined(DEBUG)std::cout << "length = " << msg.length() << " [" << msg << "]" << std::endl; #endif } void tcpsocket::send(const string& msg) { #if defined(DEBUG)std::cout << "length = " << msg.length() << " [" << msg << "]" << std::endl; #endifif (this == 0)return;int write_count;int len = msg.length();char* data = new char[len + 4];// This is length of packet.data[3] = len & 0xff;data[2] = (len >> 8) & 0xff;data[1] = (len >> 16) & 0xff;data[0] = (len >> 24) & 0xff;memcpy(data + 4, msg.c_str(), len);int total = 0;len += 4;do{write_count = ipsocket::send(data + total, len - total);if (write_count < 0){if (errno == EINTR){continue;}else{delete[] data;throw bad_file(__FILE__, __LINE__, bad_file::bad_sock, strerror(errno));}}total += write_count;} while (total < len);delete[] data ; } }?
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的linux下c/c++实例之socket服务器实例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Linux系统编程:fifo有名管道的使
- 下一篇: Linux系统编程:获取指定目录下指定文