select简单服务器(c语言)

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <unistd.h>

#define PORT 1180
#define MAXFD_SIZE 50

int fd[MAXFD_SIZE];

int main(int argc, char *argv[])
{
	int listenfd, clientfd;
	struct sockaddr_in addr;
	int maxfd = 0;
	int fd;
	int i;
	int ret;
	int rc;
	fd_set fdsr, tmpset;
	struct timeval tv;
	static char recv_msg[BUFSIZ];
	static char send_msg[BUFSIZ];

	if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		printf("socket create failure\n");
		exit(1);
	}

	bzero(&addr,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port = htons(PORT);

	if (bind(listenfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		printf("socket bind failure\n");
		exit(1);
	}

	if (listen(listenfd, 5) < 0) {
		printf("socket listen failure\n");
		exit(1);
	}

	printf("listen fd(%d)\n", listenfd);
	FD_ZERO(&fdsr);
	maxfd = listenfd;
	FD_SET(listenfd,&fdsr); 

	while (1) {
		tmpset = fdsr;
		tv.tv_sec = 10;
		tv.tv_usec =0;
		ret = select(maxfd + 1, &tmpset, NULL, NULL, &tv);
		if (ret < 0) {
			printf("select failure\n");
			exit(1);
		} else if (ret == 0) {
			//printf("select timeout\n");
			continue;
		}

		for (fd = 0; fd <= maxfd; fd++) {
			if (FD_ISSET(fd, &tmpset)) {
				if (fd == listenfd) {
					struct sockaddr_in client;
					socklen_t clilen = sizeof(client);
					if((clientfd = accept(listenfd,(struct sockaddr *)&client, &clilen)) < 0)	{
						if(errno == EINTR) {
							continue;
						} else {
							perror("accept");
							exit(1);
						}
					}
					printf("new client fd(%d)\n", clientfd);
					FD_SET(clientfd, &fdsr);
					if (clientfd > maxfd) {
						maxfd = clientfd;
					}
				} else {
					memset(recv_msg, 0x00, BUFSIZ);
					rc = recv(fd, recv_msg, BUFSIZ, 0);
					if (rc <= 0) {
						printf("close client fd(%d)\n", fd);
						close(fd);
						FD_CLR(fd, &fdsr);
						if (fd == maxfd) {
							for (i = maxfd; i > 0; i--) {
								if (FD_ISSET(i, &fdsr)) {
									maxfd = i;
									break;
								}
							}
							printf("maxfd = %d\n", maxfd);
						}
						continue;
					}

					strcpy(send_msg, recv_msg);
					send(fd, send_msg, strlen(send_msg), 0);
				}
			}
		}
	}

	return 0;
}

配一个客户端程序

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>

#define PORT 1180
#define HOST "192.168.20.169"
#define MSG_MAX 1024
#define KEEPALIVE_INTERVAL 60
#define CMD_KEEPALIVE "command=keepalive;"

int timer = 0;

char cmd[50] = {0};

void* key_monitor(void* param)
{
	printf("key_monitor start\n");
	pthread_detach(pthread_self());

	while (1) {
		if (strlen(cmd) == 0) {
			scanf("%s", cmd);
			printf("get(%s)\n", cmd);
		}
		sleep(1);
	}

	printf("key_monitor end\n");
	return NULL;
}

int main(int argc, char *argv[])
{
	int fd; 
	int len; 
	struct sockaddr_in address;
	int result;
	char send_msg[MSG_MAX] = {0};
	char recv_msg[MSG_MAX] = {0};
	int ret = 0;
	static pthread_t thread_id = 0;

	if (argc != 2) {
		perror("usage:tcpcli <IPaddress>");
		exit(1);
	}

	result = pthread_create(&thread_id, NULL, (void *)key_monitor, NULL);
	if (result != 0) {
		printf("thread create failure\n");
		return 0;
	}

	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) <= 0) {
		printf("socket create failure\n");
		return 0;
	}

	address.sin_family = AF_INET;
	address.sin_addr.s_addr = inet_addr(argv[1]);
	address.sin_port = htons(PORT);

	result = connect(fd, (struct sockaddr *)&address, sizeof(address));
	if (result == -1) {
		close(fd);
		perror("oops: client");
		exit(1);
	}

	while (1) {
		if (timer >= KEEPALIVE_INTERVAL) {
			timer = 0;
			
			strcpy(send_msg, CMD_KEEPALIVE);
			result = send(fd, send_msg, strlen(send_msg), 0);
			
			if (result < 0) {
				printf("socket send error\n");
				close(fd);
				return -1;
			}
			memset(recv_msg, 0x00, sizeof(recv_msg));
			result = recv(fd, recv_msg, MSG_MAX, 0);
			if (result < 0) {
				printf("socket recv error\n");
				close(fd);
				return -1;
			}
			
			printf("recv from server(%s)\n", recv_msg);
		}

		if (strlen(cmd) > 0) {
			if (strcmp(cmd, "q") == 0) {
				break;
			}
			strcpy(send_msg, cmd);
			result = send(fd, send_msg, strlen(send_msg), 0);
			
			if (result < 0) {
				printf("socket send error\n");
				close(fd);
				return -1;
			}
			memset(recv_msg, 0x00, sizeof(recv_msg));
			result = recv(fd, recv_msg, MSG_MAX, 0);
			if (result < 0) {
				printf("socket recv error\n");
				close(fd);
				return -1;
			}
			
			printf("recv from server(%s)\n", recv_msg);
			memset(cmd, 0x00, sizeof(cmd));
		}

		timer++;
		sleep(1);
	}
	close(fd);

	return 0; 
}

再配个Makefile

CC = -gcc
EXE = client server

all : $(EXE)

client:client.c
	$(CC) -o client client.c -lpthread -Wall

server:server.c
	$(CC) -o server server.c -Wall

clean:
	rm server client

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值