Initial commit
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#define PORT 8080
|
||||
#define TCP_PACKET_SIZE 1024 // 1KB chunks for sending
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct SDLFramework {
|
||||
SDL_Window* window;
|
||||
SDL_Renderer* renderer;
|
||||
SDL_Texture* texture;
|
||||
} SDLFramework;
|
||||
|
||||
|
||||
|
||||
int TCP_connect(int *fd) {
|
||||
int server_fd, client_fd;
|
||||
struct sockaddr_in server_addr, client_addr;
|
||||
socklen_t client_len = sizeof(client_addr);
|
||||
|
||||
// Create socket
|
||||
server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (server_fd < 0) {
|
||||
perror("Can't create socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allow port reuse
|
||||
int opt = 1;
|
||||
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||
|
||||
// Setup server address
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
server_addr.sin_port = htons(PORT);
|
||||
|
||||
// Bind socket
|
||||
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
|
||||
perror("Can't bind");
|
||||
close(server_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Listen for connections
|
||||
if (listen(server_fd, 1) < 0) {
|
||||
perror("Can't listen");
|
||||
close(server_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Server listening on port %d...\n", PORT);
|
||||
|
||||
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len);
|
||||
if (client_fd < 0) {
|
||||
perror("Can't accept");
|
||||
close(server_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Connection accepted from %s:%d\n",
|
||||
inet_ntoa(client_addr.sin_addr),
|
||||
ntohs(client_addr.sin_port));
|
||||
|
||||
fd[0] = server_fd;
|
||||
fd[1] = client_fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TCP_disconnect(int *fd) {
|
||||
close(fd[0]); // server_fd
|
||||
close(fd[1]); // client_fd
|
||||
}
|
||||
|
||||
void TCP_screen_info(int *fd, int *width, int *height, int *bpp, size_t *buffer_size) {
|
||||
recv(fd[1], width, sizeof(int), 0);
|
||||
recv(fd[1], height, sizeof(int), 0);
|
||||
recv(fd[1], bpp, sizeof(int), 0);
|
||||
*buffer_size = (*width) * (*height) * (*bpp / 8);
|
||||
|
||||
printf("width = %d\n", *width);
|
||||
printf("height = %d\n", *height);
|
||||
printf("bpp = %d\n", *bpp);
|
||||
printf("buffer_size = %zu\n", *buffer_size);
|
||||
}
|
||||
|
||||
unsigned char *TCP_receive_data(int client_fd, size_t buffer_size) {
|
||||
// Allocate the buffer with the size that the client communicated
|
||||
unsigned char *buffer = malloc(buffer_size);
|
||||
if (!buffer) {
|
||||
perror("malloc failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int total_received = 0;
|
||||
while (total_received < buffer_size) {
|
||||
// Calculate how many byte i still have to receive (could be TCP_PACKET_SIZE or less)
|
||||
int to_receive = 0;
|
||||
if (buffer_size - total_received > TCP_PACKET_SIZE) {
|
||||
to_receive= TCP_PACKET_SIZE;
|
||||
} else {
|
||||
to_receive = (buffer_size - total_received);
|
||||
}
|
||||
|
||||
// Receive the package and update the total_sent value
|
||||
int received = recv(client_fd, buffer + total_received, to_receive, 0);
|
||||
total_received += received;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void initialize_SDL(SDLFramework *framework, int width, int height) {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
framework->window = SDL_CreateWindow("Viewer", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_RESIZABLE);
|
||||
framework->renderer = SDL_CreateRenderer(framework->window, -1, SDL_RENDERER_ACCELERATED);
|
||||
framework->texture = SDL_CreateTexture(framework->renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
int fd[2]; // array containing server_fd as first element and client_fd as second
|
||||
unsigned char *buffer;
|
||||
int width;
|
||||
int height;
|
||||
int bpp;
|
||||
size_t buffer_size;
|
||||
SDLFramework framework;
|
||||
SDL_Event event;
|
||||
int windowWidth, windowHeight;
|
||||
|
||||
|
||||
// Connecting to the client and receiving the screen information
|
||||
TCP_connect(fd);
|
||||
TCP_screen_info(fd, &width, &height, &bpp, &buffer_size);
|
||||
|
||||
|
||||
initialize_SDL(&framework, width, height);
|
||||
|
||||
|
||||
|
||||
|
||||
int i=0;
|
||||
while(1){
|
||||
// Receiving from the client the buffer
|
||||
buffer = TCP_receive_data(fd[1], buffer_size);
|
||||
printf("Buffer received[%d]\n", i);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Handle the event (if quit then TODO, if resize just aknowledge (the rendering will handle this))
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
}
|
||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||
}
|
||||
}
|
||||
|
||||
// Display the image
|
||||
SDL_UpdateTexture(framework.texture, NULL, buffer, width * 4);
|
||||
SDL_RenderClear(framework.renderer);
|
||||
SDL_GetWindowSize(framework.window, &windowWidth, &windowHeight);
|
||||
SDL_Rect destRect = {0, 0, windowWidth, windowHeight};
|
||||
SDL_RenderCopy(framework.renderer, framework.texture, NULL, &destRect);
|
||||
SDL_RenderPresent(framework.renderer);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
// Cleaning
|
||||
SDL_DestroyTexture(framework.texture);
|
||||
SDL_DestroyRenderer(framework.renderer);
|
||||
SDL_DestroyWindow(framework.window);
|
||||
SDL_Quit();
|
||||
TCP_disconnect(fd);
|
||||
return 0;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user