关键字:聊天、im、表设计
时间:2018年07月

表定义

用户表
userid Int Primary
username Varchar(50) Unique
password Varchar(40)
update_at timestamp
消息表
id Int Primary
userid Int Index
ts Bigint Index
content Varchar(2000)
update_at timestamp
登录表
id Int Primary
token Varchar(50) Unique
userid Int
update_at timestamp

关键字:c语言、epoll、socket
时间:2018年7月

单线程epoll

#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define MAX_EVENTS 1000

int main(int argc, char *argv[]) {

	printf("start\n");

	int listen_sockfd;
	struct sockaddr_in listen_addr;

	memset(&listen_addr, 0 ,sizeof(listen_addr));
	listen_addr.sin_family = AF_INET;
	listen_addr.sin_addr.s_addr = INADDR_ANY;
	listen_addr.sin_port = htons(8800);

	listen_sockfd = socket(PF_INET, SOCK_STREAM, 0);
	if (listen_sockfd < 0) {
		perror("socket()");
		return 0;
	}

	int ret = bind(listen_sockfd,  (struct sockaddr *)&listen_addr, sizeof(struct sockaddr));
	if (ret<0) {
		perror("bind()");
		return 0;
	}
	printf("bind()...OK\n");

	listen(listen_sockfd, 5);

	int epoll_fd;
	epoll_fd = epoll_create(MAX_EVENTS);

	if (epoll_fd == -1) {
		perror("epoll_create()");
		return 0;
	}
	printf("epoll_create()...OK\n");

	struct epoll_event ev;
	struct epoll_event events[MAX_EVENTS];
	ev.events = EPOLLIN;
	ev.data.fd = listen_sockfd;

	if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_sockfd, &ev) == -1) {
		printf("epoll_ctl == -1\n");
		return 0;
	}
	int nfds;
	while (1) {
		nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
		if (nfds == -1) {
			perror("epoll_wait()");
			return 0;
		}
		int i;
		for (i=0;i<nfds;i++) {
			if (events[i].data.fd == listen_sockfd) {
				struct sockaddr_in client_addr;
				int sin_size = sizeof(struct sockaddr_in);
				int client_sockfd = accept(listen_sockfd, (struct sockaddr *)&client_addr, &sin_size);
				if (client_sockfd<0) {
					perror("accept()");
					return 0;
				}
				struct epoll_event event;
				event.data.fd = client_sockfd;
				event.events = EPOLLIN | EPOLLET;
				if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_sockfd, &event) == -1) {
					perror("epoll_ctl()");
					return 0;
				}
				printf("accept client %s\n", inet_ntoa(client_addr.sin_addr));
			} else {
				char buf[2048];
				int len = recv(events[i].data.fd, buf, sizeof(buf), 0);
				if (len == 0) {
					printf("recv() = 0...client %d close.\n", events[i].data.fd);
					epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, &events[i]);
					close(events[i].data.fd);
				} else if (len < 0) {
					printf("recv() < 0...client %d close.\n", events[i].data.fd); epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, &events[i]); close(events[i].data.fd); } else { printf("recv() > 0... client %d : %s\n", events[i].data.fd, buf);
				}
			}
		}
	}
	close(epoll_fd);
	close(listen_sockfd);
	return 0;
}