#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
struct line_status
{
char line[1024];
char prev_c;
int data_i;
int line_i;
};
char *parse_line(const char *data, int len, struct line_status *line_status)
{
char prev_c, c;
while (line_status->data_i < len)
{
prev_c = line_status->prev_c;
c = data[line_status->data_i];
line_status->data_i++;
line_status->prev_c = c;
if (line_status->line_i < sizeof(line_status->line) - 1)
{
line_status->line[line_status->line_i] = c;
line_status->line_i++;
}
if (prev_c == '\r' && c == '\n')
{
line_status->line[line_status->line_i] = '\0';
line_status->line_i = 0;
return line_status->line;
}
}
line_status->data_i = 0;
return NULL;
}
int str_starts_with(const char *haystack, const char *needle)
{
int a, b;
a = strlen(haystack);
b = strlen(needle);
return a >= b && memcmp(haystack, needle, b) == 0;
}
void process_client(SOCKET sock_client)
{
char data[4096];
char *line;
int len, ret;
struct line_status line_status = {0};
FD_SET readset;
SOCKADDR_IN addr = {0};
SOCKET sock_target, sock_max;
TIMEVAL timeout;
sock_target = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = inet_addr("172.32.0.93");
addr.sin_port = htons(554);
ret = connect(sock_target, (LPSOCKADDR)&addr, sizeof(addr));
if (ret == -1)
{
printf("connect() failed\n");
goto end;
}
sock_max = 0;
if (sock_max < sock_client)
sock_max = sock_client;
if (sock_max < sock_target)
sock_max = sock_target;
FD_ZERO(&readset);
timeout.tv_sec = 5;
timeout.tv_usec = 0;
while (1)
{
FD_SET(sock_client, &readset);
FD_SET(sock_target, &readset);
ret = select(sock_max + 1, &readset, NULL, NULL, &timeout);
if (ret == -1)
break;
if (FD_ISSET(sock_client, &readset))
{
printf("sock_client\n");
ret = recv(sock_client, data, sizeof(data), 0);
if (ret <= 0)
{
printf("Connection has been closed by the media player.\n");
break;
}
while (line = parse_line(data, ret, &line_status))
{
len = strlen(line);
if (!str_starts_with(line, "ClientChallenge:") && !str_starts_with(line, "PlayerStarttime:") && !str_starts_with(line, "CompanyID:") && !str_starts_with(line, "GUID:") && !str_starts_with(line, "ClientChallenge:") && !str_starts_with(line, "ClientID:") && !str_starts_with(line, "RegionData:"))
{
printf("[Send] len=%d\n%s", len, line);
send(sock_target, line, len, 0);
}
}
}
if (FD_ISSET(sock_target, &readset))
{
printf("sock_target\n");
ret = recv(sock_target, data, sizeof(data), 0);
if (ret <= 0)
{
printf("Connection has been closed by the device.\n");
break;
}
printf("[Recv] len=%d\n%.*s", ret, ret, data);
send(sock_client, data, ret, 0);
}
}
end:
closesocket(sock_target);
closesocket(sock_client);
}
void main()
{
int ret;
SOCKADDR_IN addr = {0};
SOCKET sock_client, sock_server;
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata);
sock_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
addr.sin_family = AF_INET;
addr.sin_port = htons(554);
ret = bind(sock_server, (LPSOCKADDR)&addr, sizeof(addr));
if (ret == -1)
{
printf("bind() failed. ret=%d\n", ret);
goto err;
}
listen(sock_server, 5);
ret = sizeof(addr);
sock_client = accept(sock_server, (LPSOCKADDR)&addr, &ret);
process_client(sock_client);
err:
closesocket(sock_server);
WSACleanup();
}