forked from sandsmark/kart
-
Notifications
You must be signed in to change notification settings - Fork 0
/
net.c
160 lines (143 loc) · 3.71 KB
/
net.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
#ifdef __MINGW32__
#include <winsock2.h>
#include "windowssucks/inet_v6defs.h"
#else
#include <arpa/inet.h>
#include <sys/socket.h>
#endif
#include "net.h"
static unsigned input_mask = 0;
static void die(const char *msg)
{
fprintf(stderr, "%s (%s)\n", msg, strerror(errno));
exit(1);
}
int net_start_server(int port)
{
int sockfd;
struct sockaddr_in serv;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
die("Failed to create socket");
int reuseaddr = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr));
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = INADDR_ANY;
serv.sin_port = htons(port);
if (bind(sockfd, (struct sockaddr *)&serv, sizeof(serv)) < 0)
die("Failed to bind to port");
if (listen(sockfd, 10) < 0)
die("Failed to call listen on socket");
printf("Started server on port %d\n", port);
return sockfd;
}
int net_start_client(const char *addr, int port, char **errors)
{
int sockfd;
struct sockaddr_in serv;
struct timeval tv;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
strcpy(*errors, "Failed to create socket!");
printf("Failed to create socket\n");
return -1;
}
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(port);
if (inet_pton(AF_INET, addr, &serv.sin_addr) < 1) {
strcpy(*errors, "inet_ptons failed, probably invalid address");
printf("inet_ptons failed, inet address probably not valid\n");
close(sockfd);
return -1;
}
if (connect(sockfd, (struct sockaddr *)&serv, sizeof(serv)) < 0) {
strcpy(*errors, "failed to connect to server");
printf("Failed to connect to server\n");
close(sockfd);
return -1;
}
tv.tv_sec = 1;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv));
printf("Connected to server on %s:%d\n", addr, port);
return sockfd;
}
int net_init()
{
// fuck you, windows
#ifdef __MINGW32__
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error: %d\n", err);
exit(1);
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
exit(1);
}
else
printf("The Winsock 2.2 dll was found okay\n");
#endif
return 0;
}
void net_cleanup()
{
// fuck windows for realz, do I have to clean up everything after you
#ifdef __MINGW32__
WSACleanup();
#endif
}
int net_accept(int sockfd)
{
int clientfd = accept(sockfd, (struct sockaddr*)NULL, NULL);
printf("Got connection: %d\n", clientfd);
if (clientfd < 0)
printf("accept failed\n");
return clientfd;
}
ssize_t net_recv(int sockfd, char *buf, int buf_len)
{
ssize_t n;
n = recv(sockfd, buf, buf_len, 0);
if (n > 0)
buf[n] = '\0';
return n;
}
void net_set_input(unsigned input)
{
input_mask |= input;
}
ssize_t net_send_input(int sockfd)
{
ssize_t n;
char send_buf[64];
snprintf(send_buf, 64, "%u", input_mask);
n = send(sockfd, send_buf, strlen(send_buf), 0);
input_mask = 0;
return n;
}
ssize_t net_send(int sockfd, char *msg)
{
return send(sockfd, msg, strlen(msg), 0);
}
void net_close(int sockfd)
{
close(sockfd);
}
/* vim: set ts=8 sw=8 tw=0 noexpandtab cindent softtabstop=8 :*/