-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.c
More file actions
165 lines (144 loc) · 4.6 KB
/
Copy pathserver.c
File metadata and controls
165 lines (144 loc) · 4.6 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
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
161
162
163
164
165
/*
This code is based stringly off of the base code provided in the
webpage https://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/socket.html
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
// Defining some constants
#define DEFAULT_PROTOCOL 0
#define MAX_CONNECTIONS 5
#define BUFFLEN 256
// This function is used when a system call fails
void error(char *msg) {
perror(msg);
exit(1);
}
/*
* Function: waitForConnection
* -----------------------------
* waits for a new client to connect
*
* sockfd: socket file descriptor used by server
* cli_addr: client address
* clilen: client address length
*
* returns: new file descriptor that is used for all new communication
*/
int waitForConnection(int sockfd, struct sockaddr_in cli_addr,
socklen_t clilen) {
printf("Waiting for incoming connection\n");
int newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
// accept returns -1 if an error occured
if (newsockfd < 0) {
error("ERROR on accept");
return 0;
}
// new socket was created successfully
else {
printf("New Connection created with client\n");
return newsockfd;
}
}
/*
* Function: main
* ----------------
* driver function for program
*
* argc: number of arguments passed in command line
* argv: array that holds values for command line arguments
*
* returns: 0 once completed
*/
int main(int argc, char *argv[])
{
// sockfd = socket file descriptor
// newsockfd = new socket file descriptor
// portno = port number
// n = used to determine recieved messages
int sockfd, newsockfd, portno, n;
// clilen = client address length
socklen_t clilen;
// buffer = char array that holds message contents
char buffer[BUFFLEN];
// serv_addr = server address
// cli_addr = client address
// initializing these both to 0 to clear warnings
struct sockaddr_in serv_addr, cli_addr = {0};
// check to make sure there are enough command line arguments
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
// create new socket
// AF_INET = internet domain for any two hosts on internet
// SOCK_STREAM = read characters in continuous stream
// DEFAULT_PROTOCOL = allow OS to choose appropriate protocol
sockfd = socket(AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL);
// socket() returns negative value if it fails
if (sockfd < 0) {
error("ERROR opening socket");
}
else {
printf("Socket created\n");
}
// bzero() zeros out all values in a buffer
// in this case it is zeroing out the server address to zeros
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
// INADDR_ANY allows connection to all IPs of machine
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
// binds a socket to an address, negative value returned if fails
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0) {
error("ERROR on binding");
}
else {
printf("Bind complete\n");
}
// listens on socket for connections
listen(sockfd,MAX_CONNECTIONS);
clilen = sizeof(cli_addr);
// calls waitForConnection to create new socket
newsockfd = waitForConnection(sockfd, cli_addr, clilen);
// Loop here to continue the server until user terminates
while(1) {
printf("Your message : ");
bzero(buffer,BUFFLEN);
// get user input
fgets(buffer,BUFFLEN-1,stdin);
// attempt to write message to the socket
n = write(newsockfd,buffer,strlen(buffer));
if (n < 0) {
error("ERROR writing to socket");
}
else {
printf("Message sent to client\n");
}
bzero(buffer,BUFFLEN);
printf("Waiting for client...\n");
// recv returns 0 if client properly shuts down connection
// recv returns negative val if error reading from socket
// else recv will return positive val and message will print on screen
int n = recv(newsockfd, buffer, BUFFLEN-1, 0);
if (n == 0) {
printf("Client closed connection\n");
newsockfd = waitForConnection(sockfd, cli_addr, clilen);
}
else {
if (n < 0) {
error("ERROR reading from socket");
}
else {
printf("Client : %s",buffer);
}
}
}
return 0;
}