source: Main/trunk/Server/server.c@ 9

Last change on this file since 9 was 9, checked in by Nishi, on Sep 13, 2024 at 8:28:43 PM

wip

  • Property svn:keywords set to Id
File size: 2.8 KB
RevLine 
[8]1/* $Id: server.c 9 2024-09-13 11:28:43Z nishi $ */
2
3#include "tw_server.h"
4
5#include "tw_config.h"
6
7#include <unistd.h>
8#include <string.h>
9
10#include <cm_log.h>
11
12#ifdef __MINGW32__
13#include <winsock2.h>
14#define NO_IPV6
15#else
16#include <sys/select.h>
17#include <sys/socket.h>
18#include <arpa/inet.h>
19#include <netinet/in.h>
20#include <netinet/tcp.h>
21#endif
22
23extern struct tw_config config;
24
25fd_set fdset;
26int sockcount = 0;
27
28#ifdef NO_IPV6
[9]29#define SOCKADDR struct sockaddr_in
[8]30#else
[9]31#define SOCKADDR struct sockaddr_in6
[8]32#endif
[9]33SOCKADDR addresses[MAX_PORTS];
34int sockets[MAX_PORTS];
[8]35
36void close_socket(int sock) {
37#ifdef __MINGW32__
38 closesocket(sock);
39#else
40 close(sock);
41#endif
42}
43
44int tw_server_init(void) {
45 int i;
46#ifdef __MINGW32__
47 WSADATA wsa;
48 WSAStartup(MAKEWORD(2, 0), &wsa);
49#endif
50 FD_ZERO(&fdset);
51 for(i = 0; config.ports[i] != -1; i++)
52 ;
53 sockcount = i;
54 for(i = 0; config.ports[i] != -1; i++) {
55#ifdef NO_IPV6
56 int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
57#else
58 int sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
59#endif
60#ifdef __MINGW32__
61 if(sock == INVALID_SOCKET)
62#else
63 if(sock < 0)
64#endif
65 {
66 cm_log("Server", "Socket creation failure");
67 return 1;
68 }
69 int yes = 1;
70 if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes)) < 0) {
71 close_socket(sock);
72 cm_log("Server", "setsockopt failure (reuseaddr)");
73 return 1;
74 }
75 if(setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&yes, sizeof(yes)) < 0) {
76 close_socket(sock);
77 cm_log("Server", "setsockopt failure (nodelay)");
78 return 1;
79 }
80#ifndef NO_IPV6
81 int no = 0;
82 if(setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&no, sizeof(no)) < 0) {
83 close_socket(sock);
84 cm_log("Server", "setsockopt failure (IPv6)");
85 return 1;
86 }
87#endif
88 memset(&addresses[i], 0, sizeof(addresses[i]));
89#ifdef NO_IPV6
90 addresses[i].sin_family = AF_INET;
91 addresses[i].sin_addr.s_addr = INADDR_ANY;
92 addresses[i].sin_port = htons(config.ports[i]);
93#else
94 addresses[i].sin6_family = AF_INET6;
95 addresses[i].sin6_addr = in6addr_any;
96 addresses[i].sin6_port = htons(config.ports[i]);
97#endif
98 if(bind(sock, (struct sockaddr*)&addresses[i], sizeof(addresses[i])) < 0) {
99 close_socket(sock);
100 cm_log("Server", "Bind failure");
101 return 1;
102 }
103 if(listen(sock, 128) < 0) {
104 close_socket(sock);
105 cm_log("Server", "Listen failure");
106 return 1;
107 }
[9]108 FD_SET(sock, &fdset);
[8]109 sockets[i] = sock;
110 }
111 return 0;
112}
[9]113
114void tw_server_loop(void){
115 struct timeval tv;
116 while(1){
117 tv.tv_sec = 1;
118 tv.tv_usec = 0;
119 int ret = select(sockcount, &fdset, NULL, NULL, &tv);
120 if(ret == -1){
121 break;
122 }else if(ret > 0){
123 /* connection */
124 printf("!\n");
125 int i;
126 for(i = 0; i < sockcount; i++){
127 if(FD_ISSET(sockets[i], &fdset)){
128 SOCKADDR claddr;
129 int clen = sizeof(claddr);
130 int sock = accept(sockets[i], (struct sockaddr*)&claddr, &clen);
131 close_socket(sock);
132 }
133 }
134 }
135 }
136}
Note: See TracBrowser for help on using the repository browser.