| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- #include <time.h>
- #include <stdio.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <arpa/inet.h>
- #include <sys/socket.h>
- 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;
- }
|