-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTCPListener.cpp
More file actions
121 lines (107 loc) · 2.76 KB
/
TCPListener.cpp
File metadata and controls
121 lines (107 loc) · 2.76 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
//i still dont know how many of these are relevant
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <cstring>
#include <netdb.h>
#include <fcntl.h>
#include <unistd.h>
#include "TCPListener.h"
#include "TCPStream.h"
#include "Packet.h"
TCPListener::TCPListener(int port)
{
struct sockaddr_in serv_addr;
lisfd = socket(AF_INET, SOCK_STREAM, 0);
fcntl(lisfd, F_SETFL, O_NONBLOCK);
if (lisfd < 0)
{
std::cerr << "ERROR opening socket" << std::endl;
fprintf(stderr, "%d %s\n", errno, strerror(errno));
exit(1);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
serv_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(lisfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
std::cerr << "ERROR on binding" << std::endl;
fprintf(stderr, "%d %s\n", errno, strerror(errno));
exit(1);
}
listen(lisfd, 5);
}
TCPListener::~TCPListener()
{
for (TCPStream* stream : streams)
{
delete stream;
}
::close(lisfd);
}
std::vector<TCPStream*> TCPListener::check()
{
std::vector<TCPStream*> newStreams;
//check for new connections
struct sockaddr_in cli_addr;
memset(&cli_addr, 0, sizeof(cli_addr));
socklen_t clilen = sizeof(cli_addr);
int newsockfd = accept(lisfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd > 0)
{
std::cout << "accepted fd " << newsockfd << ", moved to port " << cli_addr.sin_port << std::endl;
TCPStream* s = new TCPStream(newsockfd);
newStreams.push_back(s);
streams.push_back(s);
}
//check for data from existnig connections
for (int i = 0; i < streams.size(); i++)
{
Packet* p = streams[i]->tryReadPacket();
if (p)
{
if (p->getType() == 1) //stream has closed
{
std::cout << "stream with fd " << streams[i]->sockfd << " has disconnected" << std::endl;
delete streams[i];
streams.erase(streams.begin() + i);
i--;
}
else
{
packets.push(p);
}
}
}
return newStreams;
}
Packet* TCPListener::getPacketInQueue()
{
if (packets.size() > 0)
{
Packet* p = packets.front();
packets.pop();
return p;
}
return nullptr;
}
void TCPListener::sendToAll(Packet* p)
{
for (TCPStream* stream : streams)
{
stream->write(p);
}
}
void TCPListener::sendToAll(Packet* p, TCPStream* nstream)
{
for (TCPStream* stream : streams)
{
if (stream != nstream)
{
stream->write(p);
}
}
}