195 lines
6.9 KiB
C
195 lines
6.9 KiB
C
#include "networking.h"
|
|
#include "../defs.h"
|
|
|
|
#ifdef _WIN32
|
|
#include <winsock.h>
|
|
#else
|
|
#include <unistd.h> /* close() */
|
|
#include <sys/socket.h> /* Socket Functions */
|
|
#include <sys/types.h> /* Socket Datatypes */
|
|
#include <netinet/in.h> /* IP Datatypes */
|
|
#include <arpa/inet.h> /* Address Structs */
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/*
|
|
* Build a socket on the port_number parameter
|
|
*/
|
|
int ContructTCPSocket(unsigned short port_number)
|
|
{
|
|
int servSock; /* Server sock descriptor. */
|
|
int opt; /* Reuse ocupied port */
|
|
struct sockaddr_in ServAddr; /* Server Socket addr */
|
|
struct sockaddr_in ClntAddr; /* Client Socket addr */
|
|
|
|
opt = REUSE_PORT; /* reuse port sockopt */
|
|
/* Construct local */
|
|
/* address structure */
|
|
memset( &ServAddr, 0, sizeof(ServAddr) ); /* Zero serve struct */
|
|
memset( &ClntAddr, 0, sizeof(ClntAddr) ); /* Zero client struct */
|
|
ServAddr.sin_family = AF_INET; /* Inet addr family */
|
|
ServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming iface */
|
|
ServAddr.sin_port = htons(port_number); /* Local (server) port */
|
|
|
|
if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
|
|
DieWithError("socket() failed"); /* create socket */
|
|
|
|
if (setsockopt(servSock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1)
|
|
DieWithError("setsockopt() failed"); /* sockopt: reuse ports */
|
|
|
|
if (bind(servSock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) < 0)
|
|
DieWithError("bind() failed"); /* bind to the port */
|
|
|
|
if (listen(servSock, MAXPENDING) < 0)
|
|
DieWithError("listen() failed");
|
|
|
|
return servSock;
|
|
}
|
|
|
|
/*
|
|
* Accept a connection on the socket passed in
|
|
*/
|
|
int AcceptConnection(int server_socket)
|
|
{
|
|
int clntSock; /* client sock descriptor. */
|
|
struct sockaddr_in ClntAddr; /* Client Socket addr */
|
|
unsigned int ClntLen; /* client address *
|
|
* struct length */
|
|
ClntLen = sizeof(ClntAddr); /* Client addr length */
|
|
|
|
VPRINTF(("[PRODUCER] Waiting to accept a connection\n"));
|
|
|
|
|
|
if ((clntSock = accept(server_socket, (struct sockaddr *) &ClntAddr, &ClntLen)) < 0) {
|
|
//DieWithError("accept() failed"); /* Wait for a client to connect */
|
|
clntSock = -1; //negative socket, so it knows to ignore this connection
|
|
}
|
|
|
|
VPRINTF(("Handling client %s\n", inet_ntoa(ClntAddr.sin_addr)));
|
|
|
|
return clntSock;
|
|
}
|
|
|
|
/*
|
|
* Receive until there's nothing left to receive
|
|
* !! Fully Dynamic, must free the returned value when done
|
|
*/
|
|
int uber_recv(int sock, size_t max_to_receive, char *delimit, char **ppcData) {
|
|
char *curToRecv = malloc(max_to_receive);
|
|
|
|
char *dgramPtr;
|
|
int totalBytesRecv;
|
|
int newBytesRecv;
|
|
int i;
|
|
|
|
if (NULL == curToRecv) VPRINTF(("malloc() failed\n"));
|
|
memset(curToRecv, 0, sizeof(char)*max_to_receive);
|
|
|
|
{ // Begin For Loop
|
|
for(i=0,totalBytesRecv=0, newBytesRecv=0, dgramPtr=curToRecv;
|
|
totalBytesRecv < max_to_receive; totalBytesRecv+=newBytesRecv,i++) {
|
|
|
|
//VPRINTF(("Receiving %d Bytes. %d Bytes Total.\n",
|
|
// newBytesRecv, totalBytesRecv));
|
|
|
|
if(((newBytesRecv = recv(sock, dgramPtr,
|
|
max_to_receive - totalBytesRecv, 0)) <= 0)) {
|
|
VPRINTF(("recv() failed\n"));
|
|
free(curToRecv);
|
|
return -1;
|
|
} else {
|
|
char *curToRecv_ptr;
|
|
char *recv_tok;
|
|
dgramPtr += newBytesRecv;
|
|
//VPRINTF(("%s\n", curToRecv));
|
|
if (NULL==delimit) {
|
|
continue;
|
|
} else if(NULL != (recv_tok = strtok_r(curToRecv, delimit, &curToRecv_ptr))) {
|
|
*ppcData = curToRecv;
|
|
return totalBytesRecv;
|
|
}
|
|
}
|
|
} // End For Loop
|
|
}
|
|
*ppcData = curToRecv;
|
|
return totalBytesRecv;
|
|
}
|
|
|
|
int http_recv(int sock, size_t max_to_receive, char **ppcData) {
|
|
char *curToRecv;
|
|
|
|
char *dgramPtr;
|
|
int totalBytesRecv;
|
|
int newBytesRecv;
|
|
int i;
|
|
|
|
//check if socket closed
|
|
|
|
|
|
curToRecv = malloc(max_to_receive);
|
|
if (NULL == curToRecv) VPRINTF(("malloc() failed\n"));
|
|
memset(curToRecv, 0, sizeof(char)*max_to_receive);
|
|
|
|
{ // Begin For Loop
|
|
for(i=0,totalBytesRecv=0, newBytesRecv=0, dgramPtr=curToRecv;
|
|
totalBytesRecv < max_to_receive; totalBytesRecv+=newBytesRecv,i++) {
|
|
|
|
//VPRINTF(("Receiving %d Bytes. %d Bytes Total.\n",
|
|
// newBytesRecv, totalBytesRecv));
|
|
|
|
if(((newBytesRecv = recv(sock, dgramPtr,
|
|
max_to_receive - totalBytesRecv, 0)) <= 0)) {
|
|
VPRINTF(("recv() failed\n"));
|
|
free(curToRecv);
|
|
return 0;
|
|
} /*else {
|
|
char *curToRecv_ptr;
|
|
dgramPtr += newBytesRecv;
|
|
//VPRINTF(("%s\n", curToRecv));
|
|
|
|
if((NULL != strstr(curToRecv, "\r\n0\r\n\r\n"))) {
|
|
printf("Got End of HTTP Receive\n");
|
|
*ppcData = curToRecv;
|
|
return 0;
|
|
}
|
|
}*/
|
|
} // End For Loop
|
|
}
|
|
*ppcData = curToRecv;
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
|
|
int createTCPSocket(char *ipaddr, unsigned short server_port)
|
|
{
|
|
|
|
int sock; /* Socket descriptor */
|
|
struct sockaddr_in ServAddr; /* Address Structure */
|
|
|
|
#ifdef _WIN32
|
|
WSADATA wsaData; /* Winsock struct. */
|
|
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)/* Winsock 2.0 DLL. */
|
|
DieWithError("WSAStartup() failed");
|
|
#endif
|
|
|
|
if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
|
|
DieWithError("socket() failed");
|
|
|
|
memset(&ServAddr, 0, sizeof(ServAddr));
|
|
ServAddr.sin_family = AF_INET;
|
|
ServAddr.sin_addr.s_addr = inet_addr(ipaddr);
|
|
ServAddr.sin_port = htons(server_port);
|
|
|
|
if (connect(sock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) < 0) {
|
|
return -1;
|
|
} else {
|
|
return sock;
|
|
}
|
|
}
|
|
|