📄 network.cpp
字号:
/*
Robot Interface
(C) 2006 Jason Hunt
nulluser@gmail.com
File: network.cpp
*/
#include <windows.h>
#include <stdio.h>
#include "network.h"
#include "main.h"
#include "display.h"
#include "types.h"
#include "camera.h"
#include "robot.h"
#include "serial.h"
#include "time.h"
//extern unsigned int max_compressed;
//extern unsigned char *compressed_buffer;
unsigned int camera_port = 32459;
//extern bool remote_mode;
SOCKET listen_socket = INVALID_SOCKET; // Server will listen on this socket
SOCKET client_socket = INVALID_SOCKET; // This will be the client's socket
bool client_connected = false;
unsigned int client_updates = 0;
//HANDLE socket_sem = CreateSemaphore(NULL,1,2, NULL);
CRITICAL_SECTION network_send_lock;
double last_client_time;
/* Start socket system and setup to listen for a client */
void network_start( HWND hwnd )
{
WSADATA wsda;
WSAStartup(MAKEWORD(1, 1),&wsda);
InitializeCriticalSection(&network_send_lock);
// Create listen socket
listen_socket = socket(AF_INET, SOCK_STREAM, 0);
if (listen_socket == INVALID_SOCKET)
{
add_line("Socket error");
return;
}
u_long arg = 1; // Arg to allow non blocking
// Make accept non bocking
if (ioctlsocket(listen_socket, FIONBIO, &arg) != 0)
{
add_line("Unable to listen");
return;
}
// Setup parameters
SOCKADDR_IN server;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(camera_port);
server.sin_family = AF_INET;
// Bind socket
if (bind(listen_socket, (LPSOCKADDR) &server, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
add_line("Unable to bind");
return;
}
// Defeate Nagle Algorithm
BOOL val = TRUE;
if (setsockopt(listen_socket, IPPROTO_TCP, TCP_NODELAY, (char*)&val, sizeof(BOOL)) == SOCKET_ERROR)
{
add_line("Unable to set TCP_NODELAY");
return;
}
// Setup listen
if (listen(listen_socket, 1) == SOCKET_ERROR)
{
add_line("Unable to listen");
return;
}
// Setup message system
if (WSAAsyncSelect(listen_socket, hwnd, WM_NETEVENT, FD_READ | FD_WRITE |
FD_ACCEPT | FD_CLOSE | FD_CONNECT))
{
add_line("WSAAsyncSelect fail");
return;
}
add_line("Network Online");
}
/* End of start network */
/* Stops the network */
void network_stop( void )
{
closesocket(client_socket);
closesocket(listen_socket);
remote_mode = false;
WSACleanup();
}
/* End of shutdown_network */
/* Called when a client is trying to connect */
void network_accept(void)
{
int client_size = sizeof(sockaddr_in);
// A client is already connected
if (client_socket != INVALID_SOCKET)
{
sockaddr_in tmp_client;
// Accept to a temp socket
SOCKET tmp_socket = accept(listen_socket,(struct sockaddr*)&tmp_client, &client_size);
// Close immediately
closesocket(tmp_socket);
add_line("Another client attempted to connect");
return;
}
sockaddr_in client; // Client socket information
// Accept the client
client_socket = accept(listen_socket,(struct sockaddr*)&client, &client_size);
if (client_socket == INVALID_SOCKET)
{
add_line("Accept error.");
return;
}
// Display client address
char out[BUFFER_SIZE];
sprintf(out, "Connection from: %s", inet_ntoa(client.sin_addr));
add_line(out);
client_connected = true;
remote_mode = true;
last_client_time = get_time();
}
/* End of network accept */
void netword_send_telemetry( void )
{
unsigned char buff[50];
robot.get_telemetry(buff+1);
buff[0] = 0x90;
network_send(buff, 21);
}
/* Send the currently captured image to the client */
void network_send_image( void )
{
// SetEvent(request_image);
camera.request_image();
// camera_frames++;
// add_line("send");
// camera.get_image();
}
/* End of send_client_image */
/* Send Data to client */
int network_send(byte *data, unsigned int size)
{
bool fail = false;
EnterCriticalSection(&network_send_lock);
// Send the compressed data
if (send(client_socket, (char *)data, size, 0) == SOCKET_ERROR)
{
fail = true;
client_connected = false;
robot.reset_control();
}
LeaveCriticalSection(&network_send_lock);
return(fail);
}
/* End of network_send */
/* Called when client data is ready */
void network_read(void)
{
byte buffer[BUFFER_SIZE];
int n_bytes = recv(client_socket, (char*)buffer, BUFFER_SIZE, 0); // Get the data
if (n_bytes <= 0) return; // Error
unsigned int i = 0;
/* char b[300];
sprintf(b, "Bytes: %d", n_bytes);
if (n_bytes > 1)
add_line(b);*/
while(i < n_bytes)
{
if (buffer[i] == ROBOT_MOVEMENT)
{
last_client_time = get_time();
robot.set_control(buffer+i+1);
i += SERIAL_SEND_SIZE;
netword_send_telemetry();
}else
// if (buffer[i] == ROBOT_SENSOR_DATA) // Sensor data request
// {
// // robot_send_sensor_data();
// i++; // Skip to next
// } else
if (buffer[i] == CAMERA_IMAGE) // Image request from client
{
network_send_image(); // CLient is requesting an image
netword_send_telemetry();
i++; // Skip to next
} else
i++; // Ignore, skip to attemp resync
}
}
/* End of read_client_data */
/* Check for network remote updates */
void network_check( void )
{
if (client_connected)
{
double cur_time = get_time();
if (cur_time - last_client_time > 1)
{
add_line("Client data Timeout");
robot.reset_control();
}
}
}
/* End of network_check */
/* Deal with network messages */
void network_message(WPARAM wParam, LPARAM lParam)
{
switch (WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
network_accept();
break;
case FD_CONNECT:
break;
case FD_CLOSE:
add_line("Client disconnect");
robot.reset_control();
closesocket(client_socket);
client_socket = INVALID_SOCKET;
client_connected = false;
remote_mode = false;
break;
case FD_READ:
// make sure the socket requesting reading is our client
if (wParam == client_socket)
network_read();
break;
}
}
/* End of network_message */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -