Skip to content

Commit acce68b

Browse files
author
Ruben Sluiman
committed
Reversed the client - server allocation.
1 parent a9abde3 commit acce68b

File tree

10 files changed

+1329
-83
lines changed

10 files changed

+1329
-83
lines changed

.vscode/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"files.associations": {
3+
"xlocale": "cpp",
4+
"xmemory": "cpp"
5+
}
6+
}

Filters/Filters.cpp

Lines changed: 190 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,38 @@
2727

2828
#define DEFAULT_PORT 1100
2929

30-
DWORD WINAPI ServerThread(LPVOID lpParam);
31-
bool CheckIfPortAvailable(short int dwPort);
32-
3330
#define BUFFER_LENGTH (MAX_WIDTH * MAX_HEIGHT * 3)
3431

35-
SOCKET server_socket = INVALID_SOCKET;
36-
long bufferlength;
3732
byte* framePointer;
3833
byte frameBuffer[BUFFER_LENGTH];
3934

35+
#ifdef TCP_SERVER
36+
DWORD WINAPI ServerThread(LPVOID lpParam);
37+
bool CheckIfPortAvailable(short int dwPort);
38+
39+
SOCKET server_socket = INVALID_SOCKET;
40+
#endif // TCP_SERVER
41+
42+
struct TCPClientInfo
43+
{
44+
TCPClientInfo() {
45+
client_socket = INVALID_SOCKET;
46+
addressinfo = NULL;
47+
}
48+
TCPClientInfo(SOCKET socket_, struct addrinfo* addressinfo_) {
49+
client_socket = socket_;
50+
addressinfo = addressinfo_;
51+
}
52+
SOCKET client_socket;
53+
struct addrinfo* addressinfo = NULL;
54+
};
55+
56+
#ifdef TCP_CLIENT
57+
DWORD WINAPI ClientThread(LPVOID lpParam);
58+
59+
SOCKET client_socket = INVALID_SOCKET;
60+
TCPClientInfo client_info;
61+
#endif // TCP_CLIENT
4062

4163
#pragma region CVCam
4264
//////////////////////////////////////////////////////////////////////////
@@ -50,7 +72,7 @@ CUnknown * WINAPI CVCam::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)
5072
}
5173

5274
CVCam::CVCam(LPUNKNOWN lpunk, HRESULT *phr) :
53-
CSource(NAME("Virtual TCP Cam"), lpunk, CLSID_VirtualCam)
75+
CSource(NAME("Virtual TCP Cam"), lpunk, CLSID_VirtualCam) // Source name
5476
{
5577
//DbgLog((LOG_TRACE, 0, TEXT("Creating camera object"))); // not working somehow
5678
//DbgOutString("Hello World"); // Compile error
@@ -59,7 +81,7 @@ CVCam::CVCam(LPUNKNOWN lpunk, HRESULT *phr) :
5981
CAutoLock cAutoLock(&m_cStateLock);
6082
// Create the one and only output pin
6183
m_paStreams = (CSourceStream **) new CVCamStream*[1];
62-
stream = new CVCamStream(phr, this, L"Virtual Video");
84+
stream = new CVCamStream(phr, this, L"Virtual Video"); // Pinname
6385
m_paStreams[0] = stream;
6486
}
6587

@@ -84,14 +106,24 @@ CVCamStream::CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName) :
84106
// Set the default media type as 1920x1080 30Hz
85107
GetMediaType(0, &m_mt);
86108

109+
#ifdef TCP_SERVER
87110
//DbgLog((LOG_CUSTOM1, 1, TEXT("Starting server")));
88111
SetupServer();
89112
//DbgLog((LOG_TRACE, 3, TEXT("test string")));
113+
#endif
114+
#ifdef TCP_CLIENT
115+
SetupClient();
116+
#endif
90117
}
91118

92119
CVCamStream::~CVCamStream()
93120
{
121+
#ifdef TCP_SERVER
94122
CleanupServer();
123+
#endif
124+
#ifdef TCP_CLIENT
125+
CleanupClient();
126+
#endif
95127
}
96128

97129
HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv)
@@ -455,13 +487,11 @@ HRESULT CVCamStream::QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *
455487
//
456488
//////////////////////////////////////////////////////////////////////////
457489
#pragma region TCP Server
490+
#ifdef TCP_SERVER
458491

459492
int CVCamStream::SetupServer() {
460-
461-
bufferlength = sizeof(frameBuffer);
462493
framePointer = &frameBuffer[0];
463494

464-
465495
WSADATA wsaData;
466496
int iResult;
467497

@@ -564,90 +594,49 @@ DWORD WINAPI ServerThread(LPVOID lpParam)
564594
SOCKADDR_STORAGE from;
565595
char servstr[NI_MAXSERV],
566596
hoststr[NI_MAXHOST];
567-
int socket_type,
568-
retval,
597+
int retval,
569598
fromlen,
570599
bytecount;
571600

572601
// Retrieve the socket handle
573602
server_socket_handle = (SOCKET)lpParam;
574603

575-
// Get the socket type back
576-
fromlen = sizeof(socket_type);
577-
retval = getsockopt(server_socket_handle, SOL_SOCKET, SO_TYPE, (char*)&socket_type, &fromlen);
578-
if (retval == INVALID_SOCKET)
579-
{
580-
fprintf(stderr, "getsockopt(SO_TYPE) failed: %d\n", WSAGetLastError());
581-
goto cleanup;
582-
}
583-
584-
for (;;)
585-
{
586-
fromlen = sizeof(from);
587-
588-
if (socket_type == SOCK_STREAM)
589-
{
590-
if (client_socket != INVALID_SOCKET)
591-
{
592-
//
593-
// If we have a client connection recv and send until done
594-
//
595-
bytecount = recv(client_socket, (char*)frameBuffer, BUFFER_LENGTH, 0);
596-
if (bytecount == SOCKET_ERROR)
597-
{
598-
fprintf(stderr, "recv failed: %d\n", WSAGetLastError());
599-
goto cleanup;
600-
}
601-
else if (bytecount == 0)
602-
{
603-
// Client connection was closed
604-
retval = shutdown(client_socket, SD_SEND);
605-
if (retval == SOCKET_ERROR)
606-
{
607-
fprintf(stderr, "shutdown failed: %d\n", WSAGetLastError());
608-
goto cleanup;
609-
}
610-
611-
closesocket(client_socket);
612-
client_socket = INVALID_SOCKET;
613-
}
604+
for (;;) {
605+
if (client_socket != INVALID_SOCKET) {
606+
//
607+
// If we have a client connection recv and send until done
608+
//
609+
bytecount = recv(client_socket, (char*)frameBuffer, BUFFER_LENGTH, 0);
610+
if (bytecount == SOCKET_ERROR) {
611+
fprintf(stderr, "recv failed: %d\n", WSAGetLastError());
612+
closesocket(client_socket);
613+
client_socket = INVALID_SOCKET;
614614
}
615-
else
616-
{
617-
//
618-
// No client connection so wait for one
619-
//
620-
client_socket = accept(server_socket_handle, (SOCKADDR*)&from, &fromlen);
621-
if (client_socket == INVALID_SOCKET)
622-
{
623-
fprintf(stderr, "accept failed: %d\n", WSAGetLastError());
624-
goto cleanup;
615+
else if (bytecount == 0) {
616+
// Client connection was closed
617+
retval = shutdown(client_socket, SD_SEND);
618+
if (retval == SOCKET_ERROR) {
619+
fprintf(stderr, "shutdown failed: %d\n", WSAGetLastError());
625620
}
626621

627-
// Display the client's address
628-
retval = getnameinfo(
629-
(SOCKADDR*)&from,
630-
fromlen,
631-
hoststr,
632-
NI_MAXHOST,
633-
servstr,
634-
NI_MAXSERV,
635-
NI_NUMERICHOST | NI_NUMERICSERV
636-
);
637-
if (retval != 0)
638-
{
639-
fprintf(stderr, "getnameinfo failed: %d\n", retval);
640-
goto cleanup;
641-
}
622+
closesocket(client_socket);
623+
client_socket = INVALID_SOCKET;
624+
}
642625

643-
printf("Accepted connection from host %s and port %s\n",
644-
hoststr, servstr);
626+
} else {
627+
fromlen = sizeof(from);
628+
//
629+
// No client connection so wait for one
630+
//
631+
client_socket = accept(server_socket_handle, (SOCKADDR*)&from, &fromlen);
632+
if (client_socket == INVALID_SOCKET) {
633+
fprintf(stderr, "accept failed: %d\n", WSAGetLastError());
634+
closesocket(client_socket);
635+
client_socket = INVALID_SOCKET;
645636
}
646637
}
647638
}
648639

649-
cleanup:
650-
651640
// Close the client connection if present
652641
if (client_socket != INVALID_SOCKET)
653642
{
@@ -712,4 +701,125 @@ bool CheckIfPortAvailable(short int dwPort) {
712701
}
713702
}
714703

704+
#endif
705+
#pragma endregion
706+
707+
#pragma region TCP client
708+
#ifdef TCP_CLIENT
709+
710+
int CVCamStream::SetupClient() {
711+
framePointer = &frameBuffer[0];
712+
713+
WSAData wsaData;
714+
int iResult;
715+
SOCKET client_socket = INVALID_SOCKET;
716+
struct addrinfo* clientinfo = NULL;
717+
718+
struct addrinfo hints;
719+
720+
// Initialize Winsock
721+
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
722+
if (iResult != 0) {
723+
fprintf(stderr, "WSAStartup failed with error: %d\n", iResult);
724+
return 1;
725+
}
726+
727+
ZeroMemory(&hints, sizeof(hints));
728+
hints.ai_family = AF_INET;
729+
hints.ai_socktype = SOCK_STREAM;
730+
hints.ai_protocol = IPPROTO_TCP;
731+
732+
std::ostringstream oss;
733+
oss << DEFAULT_PORT;
734+
735+
// Resolve the server address and port
736+
iResult = getaddrinfo("localhost", oss.str().c_str(), &hints, &clientinfo);
737+
if (iResult != 0) {
738+
fprintf(stderr, "getaddrinfo failed with error: %d\n", iResult);
739+
WSACleanup();
740+
return 1;
741+
}
742+
743+
client_info = TCPClientInfo(client_socket, clientinfo);
744+
745+
client_thread = CreateThread(
746+
NULL,
747+
0,
748+
ClientThread,
749+
(LPVOID)&client_info,
750+
0,
751+
NULL
752+
);
753+
}
754+
755+
void CVCamStream::CleanupClient() {
756+
freeaddrinfo(client_info.addressinfo);
757+
closesocket(client_info.client_socket);
758+
CloseHandle(client_thread);
759+
WSACleanup();
760+
}
761+
762+
DWORD WINAPI ClientThread(LPVOID lpParam) {
763+
TCPClientInfo* client_info_handle;
764+
765+
int retval,
766+
bytecount;
767+
768+
// Retrieve the socket handle
769+
client_info_handle = (TCPClientInfo*)lpParam;
770+
SOCKET client_socket_handle = client_info_handle->client_socket;
771+
772+
for(;;) {
773+
if (client_socket_handle != INVALID_SOCKET) {
774+
//TODO: add method to request image and set format etc.
775+
776+
// Receive until the peer closes the connection
777+
bytecount = recv(client_socket_handle, (char*)frameBuffer, BUFFER_LENGTH, 0);
778+
if (bytecount == SOCKET_ERROR) {
779+
// Lost connection
780+
fprintf(stderr, "recv failed with error: %d\n", WSAGetLastError());
781+
closesocket(client_socket_handle);
782+
client_socket_handle = INVALID_SOCKET;
783+
}
784+
else if (bytecount == 0) {
785+
// shutdown the connection since no more data will be sent
786+
retval = shutdown(client_socket_handle, SD_SEND);
787+
if (retval == SOCKET_ERROR) {
788+
fprintf(stderr, "shutdown failed with error: %d\n", WSAGetLastError());
789+
closesocket(client_socket_handle);
790+
client_socket_handle = INVALID_SOCKET;
791+
}
792+
client_socket_handle = INVALID_SOCKET;
793+
}
794+
795+
} else {
796+
// Create a SOCKET for connecting to server
797+
client_socket_handle = socket(client_info_handle->addressinfo->ai_family, client_info_handle->addressinfo->ai_socktype,
798+
client_info_handle->addressinfo->ai_protocol);
799+
if (client_socket_handle == INVALID_SOCKET) {
800+
fprintf(stderr, "socket failed with error: %ld\n", WSAGetLastError());
801+
closesocket(client_socket_handle);
802+
client_socket_handle = INVALID_SOCKET;
803+
}
804+
805+
// Connect to server.
806+
retval = connect(client_socket_handle, client_info_handle->addressinfo->ai_addr, (int)client_info_handle->addressinfo->ai_addrlen);
807+
if (retval == SOCKET_ERROR) {
808+
closesocket(client_socket_handle);
809+
client_socket_handle = INVALID_SOCKET;
810+
continue;
811+
}
812+
}
813+
}
814+
815+
// Close the connection socket if needed
816+
if (client_socket_handle != INVALID_SOCKET) {
817+
closesocket(client_socket_handle);
818+
client_socket_handle = INVALID_SOCKET;
819+
}
820+
821+
return 0;
822+
}
823+
824+
#endif
715825
#pragma endregion

0 commit comments

Comments
 (0)