-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsocket_helper.h
114 lines (96 loc) · 3.89 KB
/
socket_helper.h
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
#ifndef FILE_SOCKET_HELPER
#define FILE_SOCKET_HELPER
/****************************************
Author: Tim Wood
with a little help from
http://beej.us/guide/bgnet/
A library to simplify setting up sockets. Note that using this makes you
lose control over some of the socket's data structures, so you will leak
some memory. Not a big deal for our simple examples.
****************************************/
#define BACKLOG 10 // how many pending connections queue will hold
void print_client_ip(struct sockaddr_storage client_addr){
int ipindex;
int ipaddr;
printf("Client ip: ");
for(ipindex=2;ipindex<6;ipindex++){
ipaddr=(int)(((struct sockaddr *)&client_addr)->sa_data[ipindex]);
ipaddr=(ipaddr+256)%256;
printf("%d.",ipaddr);
}
printf("\n");
}
/* Used by clients to connect to a server.
Warning: this will not properly free *server after the connection ends.
*/
int socket_connect_helper(char* server_ip, char* server_port){
int sockfd, rc;
struct addrinfo hints, *server;
/* The hints struct is used to specify what kind of server info we are looking for */
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; /* or SOCK_DGRAM */
/* getaddrinfo() gives us back a server address we can connect to.
It actually gives us a linked list of addresses, but we'll just use the first.
*/
if ((rc = getaddrinfo(server_ip, server_port, &hints, &server)) != 0) {
perror(gai_strerror(rc));
exit(-1);
}
/* Now we can create the socket and connect */
sockfd = socket(server->ai_family, server->ai_socktype, server->ai_protocol);
if (sockfd == -1) {
perror("ERROR opening socket");
exit(-1);
}
rc = connect(sockfd, server->ai_addr, server->ai_addrlen);
if (rc == -1) {
perror("ERROR on connect");
close(sockfd);
exit(-1);
}
return sockfd;
}
/* Used by server to setup a listening socket.
Warning: this will not properly free *server after the connection ends.
*/
int socket_server_helper(char* server_port) {
int yes=1;
struct addrinfo hints, *server;
int sockfd, rc;
/* The hints struct is used to specify what kind of server info we are looking for */
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; /* or SOCK_DGRAM */
hints.ai_flags = AI_PASSIVE;
/* getaddrinfo() gives us back a server address we can connect to.
The first parameter is NULL since we want an address on this host.
It actually gives us a linked list of addresses, but we'll just use the first.
*/
if (rc = getaddrinfo(NULL, server_port, &hints, &server) != 0) {
perror(gai_strerror(rc));
exit(-1);
}
/* Now we can create the socket and bind it to the local IP and port */
sockfd = socket(server->ai_family, server->ai_socktype, server->ai_protocol);
if (sockfd == -1) {
perror("ERROR opening socket");
exit(-1);
}
/* Get rid of "Address already in use" error messages */
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(-1);
}
rc = bind(sockfd, server->ai_addr, server->ai_addrlen);
if (rc == -1) {
perror("ERROR on connect");
close(sockfd);
exit(-1);
// TODO: could use goto here for error cleanup
}
/* Time to listen for clients.*/
listen(sockfd, BACKLOG);
return sockfd;
}
#endif