-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathechoserv.cpp
More file actions
130 lines (93 loc) · 3.64 KB
/
echoserv.cpp
File metadata and controls
130 lines (93 loc) · 3.64 KB
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
/*
ECHOSERV.C
==========
(c) Paul Griffiths, 1999
Email: mail@paulgriffiths.net
Simple TCP/IP echo server.
Modifications by Matthew Stoltenberg and James Hall:
* apply SO_REUSEADDR
* send and receive lines instead of just bytes
*/
#include <sys/socket.h> /* socket definitions */
#include <sys/types.h> /* socket types */
#include <arpa/inet.h> /* inet (3) funtions */
#include <unistd.h> /* misc. UNIX functions */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
/* Global constants */
#define ECHO_PORT (2002)
#define MAX_LINE (1000)
int main(int argc, char *argv[]) {
int list_s; /* listening socket */
int conn_s; /* connection socket */
short int port; /* port number */
struct sockaddr_in servaddr; /* socket address structure */
char buffer[MAX_LINE]; /* character buffer */
char *endptr; /* for strtol() */
int reuse=1; /* for setsockopt */
/* Get port number from the command line, and
set to default port if no arguments were supplied */
if ( argc == 2 ) {
port = strtol(argv[1], &endptr, 0);
if ( *endptr ) {
fprintf(stderr, "ECHOSERV: Invalid port number.\n");
exit(EXIT_FAILURE);
}
}
else if ( argc < 2 ) {
port = ECHO_PORT;
}
else {
fprintf(stderr, "ECHOSERV: Invalid arguments.\n");
exit(EXIT_FAILURE);
}
/* Create the listening socket */
if ( (list_s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
fprintf(stderr, "ECHOSERV: Error creating listening socket.\n");
exit(EXIT_FAILURE);
}
/* set SO_REUSEADDR so echoserv will be able to be re-run instantly on shutdown */
if(setsockopt(list_s, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
fprintf(stderr, "ECHOSERV: Error setting SO_REUSEADDR");
close(list_s);
exit(EXIT_FAILURE);
}
/* Set all bytes in socket address structure to
zero, and fill in the relevant data members */
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(port);
/* Bind our socket addresss to the
listening socket, and call listen() */
if ( bind(list_s, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 ) {
fprintf(stderr, "ECHOSERV: Error calling bind()\n");
exit(EXIT_FAILURE);
}
if ( listen(list_s, 2) < 0 ) {
fprintf(stderr, "ECHOSERV: Error calling listen()\n");
exit(EXIT_FAILURE);
}
/* Enter an infinite loop to respond
to client requests and echo input */
while ( 1 ) {
int bytes;
/* Wait for a connection, then accept() it */
if ( (conn_s = accept(list_s, NULL, NULL) ) < 0 ) {
fprintf(stderr, "ECHOSERV: Error calling accept()\n");
exit(EXIT_FAILURE);
}
/* Retrieve an input line from the connected socket
then simply write it back to the same socket. */
bytes = recv(conn_s, buffer, MAX_LINE-1, 0);
printf("Received: '%s'\n", buffer);
send(conn_s, buffer, bytes, 0);
/* Close the connected socket */
if ( close(conn_s) < 0 ) {
fprintf(stderr, "ECHOSERV: Error calling close()\n");
exit(EXIT_FAILURE);
}
}
}