Linux poll客户端
源代码:pollClient.cpp
/*******************************************************
* pollClient.cpp
*
* Create on 2018-10-6
* Author: yanxinchun
*
* g++ -o pollClient pollClient.cpp
*******************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/select.h>
#include <sys/time.h>
#include <signal.h>
#include <poll.h>
#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while(0)
typedef struct _packet_st {
int len;
char buf[1024];
} PACKET_st;
ssize_t readn(int fd, void *buf, size_t count)
{
size_t nleft = count;
ssize_t nread;
char *bufp = (char*)buf;
while(nleft > 0){
if(nread = read(fd, bufp, nleft) < 0) {
if(errno == EINTR) {
continue;
}
return -1;
}else if(nread == 0) {
return count - nleft;
}
bufp += nread;
nleft -= nread;
}
return count;
}
ssize_t writen(int fd, const void *buf, size_t count)
{
size_t nleft = count;
ssize_t nwritten;
char *bufp = (char*)buf;
while(nleft > 0) {
if(nwritten = write(fd, bufp, nleft) < 0) {
if(errno == EINTR) {
continue;
}
return -1;
}else if(nwritten == 0) {
continue;
}
bufp += nwritten;
nleft -= nwritten;
}
return count;
}
int getlocalip(char *ip)
{
char host[100] = {0};
if(gethostname(host, sizeof(host)) < 0) {
return -1;
}
struct hostent* hp;
if((hp = gethostbyname(host)) == NULL) {
return -1;
}
strcpy(ip, inet_ntoa(*(struct in_addr*)hp->h_addr_list[0]));
//int i = 0;
//while(hp->h_addr_list[i] != NULL) {
// printf("%s\n", inet_ntoa(*(struct in_addr*)hp->h_addr_list[i]));
// ++i;
//}
return 0;
}
void handle_sigpipe(int sig)
{
printf("[sigpipe] recv a sig=%d\n", sig);
}
int main()
{
//往一个已经关闭的socket写入数据会触发SIGPIPE
signal(SIGPIPE, handle_sigpipe);
int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock < 0) {
ERR_EXIT("socket fail!");
}
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8914);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
ERR_EXIT("connect fail!");
}
struct sockaddr_in localaddr;
socklen_t addrlen = sizeof(localaddr);
if(getsockname(sock, (struct sockaddr*)&localaddr, &addrlen) < 0){
ERR_EXIT("getsockname fail!");
}
printf("local ip=%s, port=%d\n", inet_ntoa(localaddr.sin_addr), ntohs(localaddr.sin_port));
PACKET_st recvbuf;
PACKET_st sendbuf;
memset(&recvbuf, 0, sizeof(recvbuf));
memset(&sendbuf, 0, sizeof(sendbuf));
int i;
int maxi = 1;
struct pollfd client[3];
for(i = 0; i < 3; ++i) {
client[i].fd = -1;
}
int nready = 0;
int fd_stdin = fileno(stdin);
client[0].fd = fd_stdin;
client[0].events = POLLIN;
client[1].fd = sock;
client[1].events = POLLIN;
while(1){
nready = poll(client, maxi + 1, -1);
if(nready == -1) {
if(errno == EINTR) {
continue;
}
ERR_EXIT("poll");
}
if(nready == 0) {
continue;
}
if(client[0].revents & POLLIN) {
//printf("stdin ......\n");
if(fgets(sendbuf.buf, sizeof(sendbuf.buf), stdin) == NULL){
printf("stdin is null ...\n");
shutdown(sock, SHUT_WR);
} else {
int len = strlen(sendbuf.buf);
sendbuf.len = htonl(len);
write(sock, &sendbuf, 4 + len);
memset(&sendbuf, 0, sizeof(sendbuf));
}
if(--nready <= 0) {
continue;
}
}
if(client[1].revents & POLLIN) {
//printf("sock in ......\n");
int ret = read(sock, &recvbuf.len, 4);
if(ret == -1) {
ERR_EXIT("cli read fail!");
} else if(ret < 4) {
printf("server close 1.\n");
break;
}
int n = ntohl(recvbuf.len);
ret = read(sock, &recvbuf.buf, n);
if(ret == -1) {
ERR_EXIT("cli read fail!");
} else if(ret < n) {
printf("server close 2\n");
break;
}
printf("recv: len=%d, ctx=%s", ntohl(recvbuf.len), recvbuf.buf);
//fputs(recvbuf.buf, stdout);
memset(&recvbuf, 0, sizeof(recvbuf));
if(--nready <= 0) {
continue;
}
}
}
close(sock);
return 0;
}
编译运行:
[root@QIANZI-BASE keke]# g++ -o pollClient pollClient.cpp