#include #include #include #include #include #include #include #include #include const uint16_t SERVER_PORT = 1092; const uint16_t MAX_CLIENT_NUM = 20; const uint16_t BUF_SIZE = 256; int serv_sock; // server socket int clnt_socks[MAX_CLIENT_NUM]; // client sockets struct sockaddr_in clnt_addrs[MAX_CLIENT_NUM]; // client addresses struct buffer { uint16_t ptr, len; char buf[BUF_SIZE]; } clnt_buf[MAX_CLIENT_NUM]; // client buffers // get char from client socket int sgetc(uint16_t clnt_id) { struct buffer *b = &clnt_buf[clnt_id]; if (b->ptr == b->len) { if (b->len == BUF_SIZE) { b->ptr = b->len = 0; } ssize_t n = read(clnt_socks[clnt_id], b->buf, BUF_SIZE - b->len); if (n == -1) { return -1; } if (n == 0) { return -2; } } return b->buf[b->ptr++]; } void *conn(void *id) { uint16_t clnt_id = *(uint16_t *)id; int clnt_sock = clnt_socks[clnt_id]; for (;;) { } close(clnt_sock); printf("Client %hu disconnected.\n", clnt_id); clnt_socks[clnt_id] = -1; return NULL; } void stop_server(int sig) { for (uint16_t i = 0; i < MAX_CLIENT_NUM; i++) { if (clnt_socks[i] != -1) { close(clnt_socks[i]); printf("Client %hu disconnected.\n", i); clnt_socks[i] = -1; } } close(serv_sock); puts("Stop listening."); exit(0); } int main() { memset(clnt_socks, -1, sizeof(clnt_socks)); serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (serv_sock == -1) { puts("Create socket failed."); exit(1); } struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERVER_PORT); if (bind(serv_sock, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) { puts("Bind socket failed."); exit(1); } if (listen(serv_sock, MAX_CLIENT_NUM) == -1) { puts("Listen socket failed."); exit(1); } puts("Start listening on port 1092..."); signal(SIGINT, stop_server); for (;;) { struct sockaddr_in clnt_addr; socklen_t clnt_addr_size = sizeof(clnt_addr); int clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_addr, &clnt_addr_size); if (clnt_sock == -1) { puts("Create socket failed."); continue; } for (uint16_t i = 0; i < MAX_CLIENT_NUM; i++) { if (clnt_socks[i] == -1) { clnt_socks[i] = clnt_sock; clnt_addrs[i] = clnt_addr; pthread_t pid; if (pthread_create(&pid, NULL, conn, &i) != 0) { puts("Create thread failed."); clnt_socks[i] = -1; break; } printf("Client %hu (%s:%hu) connected. pid = %lu.\n", i, inet_ntoa(clnt_addr.sin_addr), ntohs(clnt_addr.sin_port), pid); break; } } } return 0; }