当前位置:   article > 正文

Linux-TCP并发模型相关函数接口-014

Linux-TCP并发模型相关函数接口-014

1【TCP】多线程模型

相关函数接口已在前面章节介绍,这里不再赘述
  • 1

源码示例(1):

//【client.c】
int CreateTcpClient(char *pip, int port)
{
	int ret = 0;
	int sockfd = 0;
	struct sockaddr_in seraddr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}
	
	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(port);
	seraddr.sin_addr.s_addr = inet_addr(pip);
	ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
	if (-1 == ret)
	{
		perror("fail to connect");
		return -1;
	}
	
	return sockfd;
}

int main(void)
{
	int sockfd = 0;
	char tmpbuff[4096] = {"hello world"};
	int cnt = 0;
	ssize_t nsize = 0;

	sockfd = CreateTcpClient("192.168.1.183", 50000);
	
	while (1)
	{
		memset(tmpbuff, 0, sizeof(tmpbuff));
		sprintf(tmpbuff, "hello world --- %d", cnt);
		cnt++;
		nsize = send(sockfd, tmpbuff, strlen(tmpbuff), 0);
		if (-1 == nsize)
		{
			perror("fail to send");
			return -1;
		}

		memset(tmpbuff, 0, sizeof(tmpbuff));
		nsize = recv(sockfd, tmpbuff, sizeof(tmpbuff), 0);
		if (-1 == nsize)
		{
			perror("fail to recv");
			return -1;
		}

		printf("RECV:%s\n", tmpbuff);
	}

	close(sockfd);

	return 0;
}

//【server.c】
int CreateListenSocket(char *pip, int port)
{
	int ret = 0;
	int sockfd = 0;
	struct sockaddr_in seraddr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}

	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(port);
	seraddr.sin_addr.s_addr = inet_addr(pip);
	ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
	if (-1 == ret)
	{
		perror("fail to bind");
		return -1;
	}

	ret = listen(sockfd, 10);
	if (-1 == ret)
	{
		perror("fail to listen");
		return -1;
	}

	return sockfd;
}

void *HandleTcpClient(void *arg)
{
	char tmpbuff[4096] = {0};
	ssize_t nsize = 0;
	int confd = arg;
	
	while (1)
	{
		memset(tmpbuff, 0, sizeof(tmpbuff));
		nsize = recv(confd, tmpbuff, sizeof(tmpbuff), 0);
		if (-1 == nsize)
		{
			perror("fail to recv");
			return NULL;
		}
		else if (0 == nsize)
		{
			return NULL;
		}

		sprintf(tmpbuff, "%s ----echo", tmpbuff);
		nsize = send(confd, tmpbuff, strlen(tmpbuff), 0);
		if (-1 == nsize)
		{
			perror("fail to send");
			return NULL;
		}
	}

	return NULL;
}

int main(void)
{
	int sockfd = 0;
	int confd = 0;
	pthread_t tid;
	pthread_attr_t attr;

	sockfd = CreateListenSocket("192.168.1.183", 50000);
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	while (1)
	{
		confd = accept(sockfd, NULL, NULL);
		if (-1 == confd)
		{
			perror("fail to accept");
			return -1;
		}
		
		pthread_create(&tid, &attr, HandleTcpClient, confd);
	}

	close(sockfd);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157

2【IO】模型

2.1阻塞IO

相关函数接口已在前面章节介绍,这里不再赘述
  • 1

2.2非阻塞IO

源码示例(1):

//【write.c】
int main(void)
{
	int fd = 0;
	char tmpbuff[4096] = {0};

	mkfifo("/tmp/myfifo", 0664);

	fd = open("/tmp/myfifo", O_WRONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}

	while (1)
	{
		gets(tmpbuff);
		write(fd, tmpbuff, strlen(tmpbuff));
	}

	close(fd);

	return 0;
}

//【read.c】
int main(void)
{
	int fd = 0;
	int flags = 0;
	char *pret = NULL;
	ssize_t nsize = 0;
	char tmpbuff[4096] = {0};

	mkfifo("/tmp/myfifo", 0664);

	fd = open("/tmp/myfifo", O_RDONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}
	
	flags = fcntl(fd, F_GETFL);
	flags |= O_NONBLOCK;
	fcntl(fd, F_SETFL, flags);

	flags = fcntl(0, F_GETFL);
	flags |= O_NONBLOCK;
	fcntl(0, F_SETFL, flags);

	while (1)
	{
		memset(tmpbuff, 0, sizeof(tmpbuff));
		pret = gets(tmpbuff);
		if (pret != NULL)
		{
			printf("STDIN:%s\n", tmpbuff);
		}

		memset(tmpbuff, 0, sizeof(tmpbuff));
		nsize = read(fd, tmpbuff, sizeof(tmpbuff));
		if (nsize > 0)
		{
			printf("FIFO:%s\n", tmpbuff);
		}
	}

	close(fd);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

2.3异步IO

源码示例(1):

//【write.c】
int main(void)
{
	int fd = 0;
	char tmpbuff[4096] = {0};

	mkfifo("/tmp/myfifo", 0664);

	fd = open("/tmp/myfifo", O_WRONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}

	while (1)
	{
		gets(tmpbuff);
		write(fd, tmpbuff, strlen(tmpbuff));
	}

	close(fd);

	return 0;
}

//【read.c】
int fd = 0;

void handler(int signo)
{
	char tmpbuff[4096] = {0};
	ssize_t nsize = 0;

	memset(tmpbuff, 0, sizeof(tmpbuff));
	nsize = read(fd, tmpbuff, sizeof(tmpbuff));
	if (nsize > 0)
	{
		printf("FIFO:%s\n", tmpbuff);
	}

	return;
}

int main(void)
{
	int flags = 0;
	char *pret = NULL;
	ssize_t nsize = 0;
	char tmpbuff[4096] = {0};

	signal(SIGIO, handler);

	mkfifo("/tmp/myfifo", 0664);

	fd = open("/tmp/myfifo", O_RDONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}
		
	flags = fcntl(fd, F_GETFL);
	flags |= O_ASYNC;
	fcntl(fd, F_SETFL, flags);
	fcntl(fd, F_SETOWN, getpid());

	while (1)
	{
		memset(tmpbuff, 0, sizeof(tmpbuff));
		gets(tmpbuff);
		printf("STDIN:%s\n", tmpbuff);
	}

	close(fd);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

2.4多路复用IO

2.4.1【select】

2.4.1.1函数原型
【int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);】
  • 1
2.4.1.2函数功能
监听文件描述符集合中是否有文件描述编程ready状态
  • 1
2.4.1.3函数参数
1.【nfds】:最大文件描述符的值+1 
2.【readfds】:读文件描述符集合
3.【writefds】:写文件描述符集合
4.【exceptfds】:其余文件描述符集合
5.【timeout】:等待的时长
			 【NULL】:表示一直等待
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
2.4.1.4返回值
【成功】:返回文件描述符集合中的文件描述符个数
【失败】:返回【-1】
  • 1
  • 2
2.4.1.5常用的几个函数

1.【FD_CLR】

(1)函数原型:【void FD_CLR(int fd, fd_set *set);】
(2)函数功能: 将文件描述符fd从集合中清除 
(3)函数参数:
	【fd】:
	【set】:
  • 1
  • 2
  • 3
  • 4
  • 5

(4)返回值:

2.【FD_ISSET】

(1)函数原型:【int  FD_ISSET(int fd, fd_set *set);】
(2)函数功能: 判断文件描述符fd是否仍在集合中
(3)函数参数:
	【fd】:
	【set】:
(4)返回值:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.【FD_SET】

(1)函数原型:【int  FD_ISSET(int fd, fd_set *set);】
(2)函数功能: 将文件描述符fd加入到集合中
(3)函数参数:
	【fd】:
	【set】:
(4)返回值:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4.【FD_ZERO】

(1)函数原型:【int  FD_ISSET(int fd, fd_set *set);】
(2)函数功能: 将文件描述符集合清0
(3)函数参数:
【set】:
(4)返回值:
  • 1
  • 2
  • 3
  • 4
  • 5

源码示例(1):

//【write.c】
int main(void)
{
	int fd = 0;
	char tmpbuff[4096] = {0};

	mkfifo("/tmp/myfifo", 0664);

	fd = open("/tmp/myfifo", O_WRONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}

	while (1)
	{
		gets(tmpbuff);
		write(fd, tmpbuff, strlen(tmpbuff));
	}

	close(fd);

	return 0;
}


//【read.c】
int main(void)
{
	int fd = 0;
	int flags = 0;
	char *pret = NULL;
	ssize_t nsize = 0;
	char tmpbuff[4096] = {0};
	fd_set rdfds;
	fd_set tmpfds;
	int ret = 0;

	mkfifo("/tmp/myfifo", 0664);

	fd = open("/tmp/myfifo", O_RDONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}
	
	FD_ZERO(&rdfds);
	FD_SET(fd, &rdfds);
	FD_SET(0, &rdfds);

	while (1)
	{
		tmpfds = rdfds;
		ret = select(fd+1, &tmpfds, NULL, NULL, NULL);
		if (-1 == ret)
		{
			perror("fail to select");
			return -1;
		}

		if (FD_ISSET(fd, &tmpfds))
		{
			memset(tmpbuff, 0, sizeof(tmpbuff));
			read(fd, tmpbuff, sizeof(tmpbuff));
			printf("FIFO:%s\n", tmpbuff);
		}

		if (FD_ISSET(0, &tmpfds))
		{
			memset(tmpbuff, 0, sizeof(tmpbuff));
			gets(tmpbuff);
			printf("STDIN:%s\n", tmpbuff);
		}
	}

	close(fd);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

源码示例(2):

//【client.c】
int CreateTcpClient(char *pip, int port)
{
	int ret = 0;
	int sockfd = 0;
	struct sockaddr_in seraddr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}
	
	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(port);
	seraddr.sin_addr.s_addr = inet_addr(pip);
	ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
	if (-1 == ret)
	{
		perror("fail to connect");
		return -1;
	}
	
	return sockfd;
}

int main(void)
{
	int sockfd = 0;
	char tmpbuff[4096] = {"hello world"};
	int cnt = 0;
	ssize_t nsize = 0;

	sockfd = CreateTcpClient("192.168.1.183", 50000);
	
	while (1)
	{
		memset(tmpbuff, 0, sizeof(tmpbuff));
		sprintf(tmpbuff, "hello world --- %d", cnt);
		cnt++;
		nsize = send(sockfd, tmpbuff, strlen(tmpbuff), 0);
		if (-1 == nsize)
		{
			perror("fail to send");
			return -1;
		}

		memset(tmpbuff, 0, sizeof(tmpbuff));
		nsize = recv(sockfd, tmpbuff, sizeof(tmpbuff), 0);
		if (-1 == nsize)
		{
			perror("fail to recv");
			return -1;
		}

		printf("RECV:%s\n", tmpbuff);
	}

	close(sockfd);

	return 0;
}


//【server.c】
int CreateListenSocket(char *pip, int port)
{
	int ret = 0;
	int sockfd = 0;
	struct sockaddr_in seraddr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}

	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(port);
	seraddr.sin_addr.s_addr = inet_addr(pip);
	ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
	if (-1 == ret)
	{
		perror("fail to bind");
		return -1;
	}

	ret = listen(sockfd, 10);
	if (-1 == ret)
	{
		perror("fail to listen");
		return -1;
	}

	return sockfd;
}

int HandleTcpClient(int confd)
{
	char tmpbuff[4096] = {0};
	ssize_t nsize = 0;

	memset(tmpbuff, 0, sizeof(tmpbuff));
	nsize = recv(confd, tmpbuff, sizeof(tmpbuff), 0);
	if (-1 == nsize)
	{
		perror("fail to recv");
		return -1;
	}
	else if (0 == nsize)
	{
		return 0;
	}

	sprintf(tmpbuff, "%s ----echo", tmpbuff);
	nsize = send(confd, tmpbuff, strlen(tmpbuff), 0);
	if (-1 == nsize)
	{
		perror("fail to send");
		return -1;
	}

	return nsize;
}

int main(void)
{
	int sockfd = 0;
	int confd = 0;
	fd_set rdfds;
	fd_set tmpfds;
	int maxfd = 0;
	int ret = 0;
	int i = 0;

	sockfd = CreateListenSocket("192.168.1.183", 50000);
	
	FD_ZERO(&rdfds);
	FD_SET(sockfd, &rdfds);
	maxfd = sockfd;

	while (1)
	{
		tmpfds = rdfds;
		ret = select(maxfd+1, &tmpfds, NULL, NULL, NULL);
		if (-1 == ret)
		{
			perror("fail to select");
			return -1;
		}
		
		if (FD_ISSET(sockfd, &tmpfds))
		{
			confd = accept(sockfd, NULL, NULL);
			if (-1 == confd)
			{
				perror("fail to accept");
				FD_CLR(sockfd, &rdfds);
				close(sockfd);
				continue;
			}

			FD_SET(confd, &rdfds);
			maxfd = maxfd > confd ? maxfd : confd;
		}
		
		for (i = sockfd+1; i <= maxfd; i++)
		{
			if (FD_ISSET(i, &tmpfds))
			{
				ret = HandleTcpClient(i);
				if (-1 == ret)
				{
					fprintf(stderr, "handle client failed!\n");
					FD_CLR(i, &rdfds);
					close(i);
					continue;
				}
				else if (0 == ret)
				{
					fprintf(stderr, "client disconnected!\n");
					FD_CLR(i, &rdfds);
					close(i);
					continue;
				}
			}
		}
	}

	close(confd);
	close(sockfd);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196

2.4.2【poll】

2.4.2.1函数原型
【int poll(struct pollfd *fds, nfds_t nfds, int timeout);】
  • 1
2.4.2.2函数功能
监听文件描述符集合是否有事件发生
  • 1
2.4.2.3函数参数
1.【fds】:监听文件描述符集合数组空间首地址
2.【nfds】:监听文件描述符集合元素个数
3.【timeout】:等待的时间
		【-1】: 一直等待
  • 1
  • 2
  • 3
  • 4

结构体说明:

struct pollfd {
     int   fd;/* file descriptor 监听的文件描述符*/
     short events;/* requested events 要监听的事件*/
     short revents;/* returned events 实际产生的事件*/
};
//结构体成员介绍
fd:监听的文件描述符
events:要监听的事件  
		POLLIN:是否可读  
		POLLOUT:是否可写
revents:实际产生的事件 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
2.4.2.4返回值
【成功】:返回产生事件的文件描述符个数
【失败】:返回【-1】
  • 1
  • 2

源码示例(1):

//【write.c】
int main(void)
{
	int fd = 0;
	char tmpbuff[4096] = {0};

	mkfifo("/tmp/myfifo", 0664);

	fd = open("/tmp/myfifo", O_WRONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}

	while (1)
	{
		gets(tmpbuff);
		write(fd, tmpbuff, strlen(tmpbuff));
	}

	close(fd);

	return 0;
}

//【read.c】
int main(void)
{
	int fd = 0;
	int flags = 0;
	char *pret = NULL;
	ssize_t nsize = 0;
	char tmpbuff[4096] = {0};
	struct pollfd fds[2];
	int nready = 0;

	mkfifo("/tmp/myfifo", 0664);

	fd = open("/tmp/myfifo", O_RDONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}
	
	fds[0].fd = fd;
	fds[0].events = POLLIN;
	fds[1].fd = 0;
	fds[1].events = POLLIN;

	while (1)
	{
		nready = poll(fds, 2, -1);
		if (-1 == nready)
		{
			perror("fail to poll");
			return -1;
		}

		if (fds[0].revents & POLLIN)
		{
			memset(tmpbuff, 0, sizeof(tmpbuff));
			read(fd, tmpbuff, sizeof(tmpbuff));
			printf("FIFO:%s\n", tmpbuff);
		}
	
		if (fds[1].revents & POLLIN)
		{
			memset(tmpbuff, 0, sizeof(tmpbuff));
			gets(tmpbuff);
			printf("STDIN:%s\n", tmpbuff);
		}
	}

	close(fd);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77

源码示例(2):

//【client.c】
int CreateTcpClient(char *pip, int port)
{
	int ret = 0;
	int sockfd = 0;
	struct sockaddr_in seraddr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}
	
	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(port);
	seraddr.sin_addr.s_addr = inet_addr(pip);
	ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
	if (-1 == ret)
	{
		perror("fail to connect");
		return -1;
	}
	
	return sockfd;
}

int main(void)
{
	int sockfd = 0;
	char tmpbuff[4096] = {"hello world"};
	int cnt = 0;
	ssize_t nsize = 0;

	sockfd = CreateTcpClient("192.168.1.183", 50000);
	
	while (1)
	{
		memset(tmpbuff, 0, sizeof(tmpbuff));
		sprintf(tmpbuff, "hello world --- %d", cnt);
		cnt++;
		nsize = send(sockfd, tmpbuff, strlen(tmpbuff), 0);
		if (-1 == nsize)
		{
			perror("fail to send");
			return -1;
		}

		memset(tmpbuff, 0, sizeof(tmpbuff));
		nsize = recv(sockfd, tmpbuff, sizeof(tmpbuff), 0);
		if (-1 == nsize)
		{
			perror("fail to recv");
			return -1;
		}

		printf("RECV:%s\n", tmpbuff);
	}

	close(sockfd);

	return 0;
}


//【server.c】
int CreateListenSocket(char *pip, int port)
{
	int ret = 0;
	int sockfd = 0;
	struct sockaddr_in seraddr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}

	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(port);
	seraddr.sin_addr.s_addr = inet_addr(pip);
	ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
	if (-1 == ret)
	{
		perror("fail to bind");
		return -1;
	}

	ret = listen(sockfd, 10);
	if (-1 == ret)
	{
		perror("fail to listen");
		return -1;
	}

	return sockfd;
}

int HandleTcpClient(int confd)
{
	char tmpbuff[4096] = {0};
	ssize_t nsize = 0;

	memset(tmpbuff, 0, sizeof(tmpbuff));
	nsize = recv(confd, tmpbuff, sizeof(tmpbuff), 0);
	if (-1 == nsize)
	{
		perror("fail to recv");
		return -1;
	}
	else if (0 == nsize)
	{
		return 0;
	}

	sprintf(tmpbuff, "%s ----echo", tmpbuff);
	nsize = send(confd, tmpbuff, strlen(tmpbuff), 0);
	if (-1 == nsize)
	{
		perror("fail to send");
		return -1;
	}

	return nsize;
}

int InitFds(struct pollfd *fds, int maxlen)
{
	int i = 0;

	for (i = 0; i < maxlen; i++)
	{
		fds[i].fd = -1;
	}

	return 0;
}

int AddFd(struct pollfd *fds, int maxlen, int fd, short env)
{
	int i = 0;

	for (i = 0; i < maxlen; i++)
	{
		if (fds[i].fd == -1)
		{
			fds[i].fd = fd;
			fds[i].events = env;

			break;
		}
	}

	if (i == maxlen)
	{
		return -1;
	}

	return 0;
}

int DeleteFd(struct pollfd *fds, int maxlen, int fd)
{
	int i = 0;

	for (i = 0; i < maxlen; i++)
	{
		if (fds[i].fd == fd)
		{
			fds[i].fd = -1;
			break;
		}
	}

	return 0;
}

int main(void)
{
	int sockfd = 0;
	int confd = 0;
	struct pollfd fds[1024];
	int nready = 0;
	int i = 0;
	int ret = 0;

	sockfd = CreateListenSocket("192.168.1.183", 50000);
	
	InitFds(fds, 1024);
	AddFd(fds, 1024, sockfd, POLLIN);

	while (1)
	{
		nready = poll(fds, 1024, -1);
		if (-1 == nready)
		{
			perror("fail to poll");
			return -1;
		}
		
		for (i = 0; i < 1024; i++)
		{
			if (fds[i].fd == -1)
			{
				continue;
			}

			if (fds[i].revents & POLLIN && fds[i].fd == sockfd)
			{
				confd = accept(sockfd, NULL, NULL);
				if (-1 == confd)
				{
					perror("fail to accept");
					DeleteFd(fds, 1024, sockfd);
					close(sockfd);
					continue;
				}
				
				AddFd(fds, 1024, confd, POLLIN);
			}
			else if (fds[i].revents & POLLIN && fds[i].fd != sockfd)
			{
				ret = HandleTcpClient(fds[i].fd);
				if (-1 == ret)
				{
					fprintf(stderr, "handle tcp client failed!\n");
					close(fds[i].fd);
					DeleteFd(fds, 1024, fds[i].fd);
					continue;
				}
				else if (0 == ret)
				{
					fprintf(stderr, "client disconnected!\n");
					close(fds[i].fd);
					DeleteFd(fds, 1024, fds[i].fd);
					continue;
				}
			}
		}
	}

	close(sockfd);

	return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247

2.4.3【epoll】

2.4.3.1函数原型

【int epoll_create(int size);】

2.4.3.2函数功能
创建一张内核事件表
  • 1
2.4.3.3函数参数
【size】:事件的个数
  • 1
2.4.3.4返回值
【成功】:返回文件描述符
【失败】:返回【-1】
  • 1
  • 2

2.4.4【epoll_ctl】

2.4.4.1函数原型

【int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);】

2.4.4.2函数功能

维护epoll时间表

2.4.4.3函数参数
1.【epfd】:事件表的文件描述符
2.【op】:
	【EPOLL_CTL_ADD】:添加事件
	【EPOLL_CTL_MOD】:修改事件
	【EPOLL_CTL_DEL】:删除事件
3.【fd】:操作的文件描述符
4.【event】:事件对应的事件
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

结构体说明:

typedef union epoll_data {
	void        *ptr;
	int          fd;
	uint32_t     u32;
	uint64_t     u64;
} epoll_data_t;

struct epoll_event {
	uint32_t     events;      /* Epoll events */
	epoll_data_t data;        /* User data variable */
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
2.4.4.4返回值
【成功】:返回【0】 
【失败】:返回【-1】
  • 1
  • 2

2.4.5【epoll_wait】

2.4.5.1函数原型
【int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);】
  • 1
2.4.5.2函数功能
监听事件表中的事件
  • 1
2.4.5.3函数参数
1.【epfd】:文件描述符
2.【events】:存放实际产生事件的数组空间首地址
3.【maxevents】:最多存放事件的个数
4.【timeout】:设定监听的时间(超过该时间则不再监听)
			【-1】:一直监听直到有事件发生
  • 1
  • 2
  • 3
  • 4
  • 5
2.4.5.4返回值
【成功】:返回产生事件的文件描述符个数
【失败】:返回【-1】
【超时】:如果时间达到仍没有事件发生返回【0】
  • 1
  • 2
  • 3

源码示例(1):

//【write.c】
int main(void)
{
	int fd = 0;
	char tmpbuff[4096] = {0};

	mkfifo("/tmp/myfifo", 0664);

	fd = open("/tmp/myfifo", O_WRONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}

	while (1)
	{
		gets(tmpbuff);
		write(fd, tmpbuff, strlen(tmpbuff));
	}

	close(fd);

	return 0;
}



//【read.c】
int main(void)
{
	int fd = 0;
	int flags = 0;
	char *pret = NULL;
	ssize_t nsize = 0;
	char tmpbuff[4096] = {0};
	int epfd = 0;
	struct epoll_event env;
	struct epoll_event retenv[2];
	int nready = 0;
	int i = 0;

	mkfifo("/tmp/myfifo", 0664);

	fd = open("/tmp/myfifo", O_RDONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}

	epfd = epoll_create(2);
	if (-1 == epfd)
	{
		perror("fail to epoll_create");
		return -1;
	}
	
	env.events = EPOLLIN;
	env.data.fd = fd;
	epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &env);

	env.events = EPOLLIN;
	env.data.fd = 0;
	epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &env);

	while (1)
	{
		nready = epoll_wait(epfd, retenv, 2, -1);
		if (-1 == nready)
		{
			perror("fail to epoll_wait");
			return -1;
		}
		
		for (i = 0; i < nready; i++)
		{
			if (retenv[i].data.fd == 0)
			{
				memset(tmpbuff, 0, sizeof(tmpbuff));
				gets(tmpbuff);
				printf("STDIN:%s\n", tmpbuff);
			}
			else if (retenv[i].data.fd == fd)
			{
				memset(tmpbuff, 0, sizeof(tmpbuff));
				read(fd, tmpbuff, sizeof(tmpbuff));
				printf("FIFO:%s\n", tmpbuff);
			}
		}
	}

	close(fd);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

源码示例(2):

//【client.c】
int CreateTcpClient(char *pip, int port)
{
	int ret = 0;
	int sockfd = 0;
	struct sockaddr_in seraddr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}
	
	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(port);
	seraddr.sin_addr.s_addr = inet_addr(pip);
	ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
	if (-1 == ret)
	{
		perror("fail to connect");
		return -1;
	}
	
	return sockfd;
}

int main(void)
{
	int sockfd = 0;
	char tmpbuff[4096] = {"hello world"};
	int cnt = 0;
	ssize_t nsize = 0;

	sockfd = CreateTcpClient("192.168.1.183", 50000);
	
	while (1)
	{
		memset(tmpbuff, 0, sizeof(tmpbuff));
		sprintf(tmpbuff, "hello world --- %d", cnt);
		cnt++;
		nsize = send(sockfd, tmpbuff, strlen(tmpbuff), 0);
		if (-1 == nsize)
		{
			perror("fail to send");
			return -1;
		}

		memset(tmpbuff, 0, sizeof(tmpbuff));
		nsize = recv(sockfd, tmpbuff, sizeof(tmpbuff), 0);
		if (-1 == nsize)
		{
			perror("fail to recv");
			return -1;
		}

		printf("RECV:%s\n", tmpbuff);
	}

	close(sockfd);

	return 0;
}



//【server.c】
int CreateListenSocket(char *pip, int port)
{
	int ret = 0;
	int sockfd = 0;
	struct sockaddr_in seraddr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}

	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(port);
	seraddr.sin_addr.s_addr = inet_addr(pip);
	ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
	if (-1 == ret)
	{
		perror("fail to bind");
		return -1;
	}

	ret = listen(sockfd, 10);
	if (-1 == ret)
	{
		perror("fail to listen");
		return -1;
	}

	return sockfd;
}

int HandleTcpClient(int confd)
{
	char tmpbuff[4096] = {0};
	ssize_t nsize = 0;

	memset(tmpbuff, 0, sizeof(tmpbuff));
	nsize = recv(confd, tmpbuff, sizeof(tmpbuff), 0);
	if (-1 == nsize)
	{
		perror("fail to recv");
		return -1;
	}
	else if (0 == nsize)
	{
		return 0;
	}

	sprintf(tmpbuff, "%s ----echo", tmpbuff);
	nsize = send(confd, tmpbuff, strlen(tmpbuff), 0);
	if (-1 == nsize)
	{
		perror("fail to send");
		return -1;
	}

	return nsize;
}

int AddFd(int epfd, int fd, uint32_t env)
{
	struct epoll_event tmpenv;
	int ret = 0;
	
	tmpenv.events = env;
	tmpenv.data.fd = fd;
	ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &tmpenv);
	if (-1 == ret)
	{
		perror("fail to epoll_ctl");
		return -1;
	}

	return 0;
}

int DeleteFd(int epfd, int fd)
{
	int ret = 0;

	ret = epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
	if (-1 == ret)
	{
		perror("fail to epoll_ctl");
		return -1;
	}

	return 0;
}

int main(void)
{
	int sockfd = 0;
	int confd = 0;
	int epfd = 0;
	int nready = 0;
	int i = 0;
	int ret = 0;
	struct epoll_event retenv[1024];

	sockfd = CreateListenSocket("192.168.1.183", 50000);
	
	epfd = epoll_create(1024);
	if (-1 == epfd)
	{
		perror("fail to epoll_create");
		return -1;
	}

	AddFd(epfd, sockfd, EPOLLIN);

	while (1)
	{
		nready = epoll_wait(epfd, retenv, 1024, -1);
		if (-1 == nready)
		{
			perror("fail to epoll_wait");
			return -1;
		}
		
		for (i = 0; i < nready; i++)
		{
			if (retenv[i].data.fd == sockfd)
			{
				confd = accept(sockfd, NULL, NULL);
				if (-1 == confd)
				{
					perror("fail to accept");
					DeleteFd(epfd, sockfd);
					close(sockfd);
					continue;
				}

				AddFd(epfd, confd, EPOLLIN);
			}
			else if (retenv[i].data.fd != sockfd)
			{
				ret = HandleTcpClient(retenv[i].data.fd);
				if (-1 == ret)
				{
					fprintf(stderr, "handle tcp client failed!\n");
					DeleteFd(epfd, retenv[i].data.fd);
					close(retenv[i].data.fd);
					continue;
				}
				else if (0 == ret)
				{
					fprintf(stderr, "tcp client disconnected!\n");
					DeleteFd(epfd, retenv[i].data.fd);
					close(retenv[i].data.fd);
					continue;
				}
			}
		}
	}

	close(epfd);
	close(sockfd);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号