作业--day34

使用select完成TCP并发服务器和客户端

server.c

#include 

#define PORT 8888
#define IP "192.168.125.137"

int main(int argc, const char *argv[])
{
	int sfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sfd == -1){
		perror("socket error");
		return -1;
	}

	int reuse = -1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){
		perror("setsockopt error");
		return -1;
	}

	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);
	if(bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) == -1){
		perror("bind error");
		return -1;
	}

	if(listen(sfd, 128) == -1){
		perror("listen error");
		return -1;
	}

	struct sockaddr_in cin;
	socklen_t socklen = sizeof(cin);
	char buf[128] = "";

	fd_set readfds;
	FD_ZERO(&readfds);

	FD_SET(0, &readfds);
	FD_SET(sfd, &readfds);

	int res = -1;
	fd_set tempfds;
	struct sockaddr_in arr_cin[1024];
	int maxfd = sfd;

	while(1){

		tempfds = readfds;
		res = select(maxfd+1, &tempfds, NULL, NULL, NULL);
		if(res == -1){
			perror("select error");
			return -1;
		}else if(res == 0){
			puts("time out");
			return -1;
		}

		for(int index=0; index<=maxfd; index++){
			if(!FD_ISSET(index, &tempfds)){
				continue;
			}

			if(index == sfd){

				int newfd = accept(sfd, (struct sockaddr *)&cin, &socklen);
				if(newfd == -1){
					perror("accept error");
					return -1;
				}
				arr_cin[newfd] = cin;
				printf("[%s: %d] 已连接\n", inet_ntoa(arr_cin[newfd].sin_addr), ntohs(arr_cin[newfd].sin_port));

				FD_SET(newfd, &readfds);
				if(newfd > maxfd){
					maxfd = newfd;
				}

			}else if(index == 0){

				fgets(buf, sizeof(buf), stdin);
				buf[strlen(buf) - 1] = 0;
				for(int i=4; i<=maxfd; i++){
					send(i, buf, sizeof(buf), 0);
				}

			}else{
				
				bzero(buf, sizeof(buf));

				int res = recv(index, buf, sizeof(buf), 0);
				if(res == 0){
					puts("客户端已下线");
					close(index);
					FD_CLR(index, &readfds);
					for(int i=maxfd; i>0; i--){
						if(FD_ISSET(i, &readfds)){
							maxfd = i;
							break;
						}
					}
					continue;
				}
				printf("[%s: %d] %s\n", inet_ntoa(arr_cin[index].sin_addr), ntohs(arr_cin[index].sin_port), buf);

				strcat(buf, "*_*");
				send(index, buf, sizeof(buf), 0);

			}

		}


	}

	close(sfd);
	return 0;
}

client.c

#include 

#define PORT 8888
#define IP "192.168.125.137"

int main(int argc, const char *argv[])
{
	int cfd = socket(AF_INET, SOCK_STREAM, 0);
	if(cfd == -1){
		perror("socket error");
		return -1;
	}

	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);

	if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){
		perror("connect error");
		return -1;
	}

	fd_set readfds;
	fd_set tempfds;

	FD_ZERO(&readfds);
	FD_SET(0, &readfds);
	FD_SET(cfd, &readfds);

	int res = -1;
	struct sockaddr_in arr_cin[1024];
	char buf[128] = "";

	while(1){

		tempfds = readfds;
		res = select(cfd+1, &tempfds, NULL, NULL, NULL);
		if(res == -1){
			perror("select error");
			return -1;
		}else if(res == 0){
			puts("time out");
			return -1;
		}
		if(FD_ISSET(cfd, &tempfds)){

			bzero(buf, sizeof(buf));
			res = recv(cfd, buf, sizeof(buf), 0);
			if(res == 0){
				puts("服务器已下线");
				break;
			}
			printf("[%s: %d] %s\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), buf);

		}

		if(FD_ISSET(0, &tempfds)){

			bzero(buf, sizeof(buf));
			fgets(buf, sizeof(buf), stdin);
			buf[strlen(buf) - 1] = 0;
			send(cfd, buf, sizeof(buf), 0);

		}

	}

	close(cfd);
	return 0;
}

作业--day34_第1张图片

使用poll完成TCP并发服务器和客户端

server.c

#include 

#define PORT 8888
#define IP "192.168.125.137"

void del_arr(struct pollfd fds[], int *max, int index){
	for(int i=index; i<(*max)-1; i++){
		fds[i] = fds[i+1];
	}
	(*max) -= 1;
}

int main(int argc, const char *argv[])
{
	int sfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sfd == -1){
		perror("socket error");
		return -1;
	}

	int reuse = -1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){
		perror("setsockopt error");
		return -1;
	}

	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);
	if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){
		perror("bind error");
		return -1;
	}

	if(listen(sfd, 128) == -1){
		perror("listen error");
		return -1;
	}

	struct sockaddr_in cin;
	socklen_t socklen = sizeof(cin);

	char buf[128] = "";
	int res = -1;

	struct pollfd fds[1024];
	fds[0].fd = 0;
	fds[0].events = POLLIN;

	fds[1].fd = sfd;
	fds[1].events = POLLIN;

	struct sockaddr_in arr_cin[1024];
	int newfd = -1;
	int max = 2;

	while(1){

		res = poll(fds, max, -1);
		if(res < 0){
			perror("poll error");
			return -1;
		}else if(res == 0){
			puts("time out");
			return -1;
		}

		for(int index=0; index<max; index++){
			if(fds[index].revents == POLLIN){

				if(index == 0){

					bzero(buf, sizeof(buf));
					fgets(buf, sizeof(buf), stdin);
					buf[strlen(buf) - 1] = 0;
					
					for(int i=2; i<max; i++){
						send(fds[i].fd, buf, sizeof(buf), 0);
					}

				}else if(index == 1){

					if((newfd = accept(fds[index].fd, (struct sockaddr*)&cin, &socklen)) == -1){
						perror("accept error");
						return -1;
					}
					fds[max].fd = newfd;
					fds[max].events = POLLIN;
					max++;
					arr_cin[newfd] = cin;
					printf("[%s: %d] 已上线\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
					
				}else{
					
					bzero(buf, sizeof(buf));
					res = recv(fds[index].fd, buf, sizeof(buf), 0);
					if(res == 0){
						puts("客户端已下线");
						del_arr(fds, &max, index);
						continue;
					}
					printf("[%s: %d] %s\n", inet_ntoa(arr_cin[fds[index].fd].sin_addr), ntohs(arr_cin[fds[index].fd].sin_port), buf);

				}

			}
		}
	}

	close(sfd);
	return 0;
}

client.c

#include 

#define PORT 8888
#define IP "192.168.125.137"

int main(int argc, const char *argv[])
{
	int sfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sfd == -1){
		perror("socket error");
		return -1;
	}

	int reuse = -1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){
		perror("setsockopt error");
		return -1;
	}

	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);
	if(connect(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){
		perror("connect error");
		return -1;
	}

	char buf[128] = "";
	int res = -1;

	struct pollfd fds[2];
	fds[0].fd = 0;
	fds[0].events = POLLIN;

	fds[1].fd = sfd;
	fds[1].events = POLLIN;
	

	while(1){

		res = poll(fds, 2, -1);
		if(res < 0){
			perror("poll error");
			return -1;
		}else if(res == 0){
			puts("time out");
			return -1;
		}

		if(fds[0].revents == POLLIN){
			bzero(buf, sizeof(buf));
			fgets(buf, sizeof(buf), stdin);
			buf[strlen(buf) - 1] = 0;
			send(sfd, buf, sizeof(buf), 0);
		}

		if(fds[1].revents == POLLIN){
			bzero(buf, sizeof(buf));
			res = recv(sfd, buf, sizeof(buf), 0);
			if(res == 0){
				puts("服务器已下线");
				break;
			}
			printf("[%s: %d] %s\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), buf);
		}
	}

	close(sfd);
	return 0;
}

作业--day34_第2张图片

思维导图

作业--day34_第3张图片

你可能感兴趣的:(c语言)