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);
Related
I wrote this C code that uses the libssh2 library to connect to a ssh server and get the output of a command executed on the server.
Currently the code works fine, it's connecting to the ssh server and obtains the output of executed command from custom_command variable.
The problem is that I want to make it obtain the output of two commands, for example to obtain the output of custom_command and custom_command2 variables in the same libssh2 channel.
I tried with this but it doesen't work
while((rc = libssh2_channel_exec(channel, custom_command)) == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(s_sock, session);
}
while((rc = libssh2_channel_exec(channel, custom_command2)) == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(s_sock, session);
}
Does anyone know how I can modify this code to work as I said above?
//COMPILE COMMAND: gcc program.c -o program -lssh2
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include "libssh2_config.h"
#include <libssh2.h>
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
{
struct timeval timeout;
int rc, dir;
fd_set fd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(socket_fd, &fd);
dir = libssh2_session_block_directions(session);
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
{
readfd = &fd;
}
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
{
writefd = &fd;
}
rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
return rc;
}
int main()
{
//LOGIN CREDENTIALS
char *hostname = "127.0.0.1";
char *username = "vboxuser";
char *password = "changeme";
char *custom_command = "uptime";
char *custom_command2 = "hostname"
int port = 22;
int s_sock;
struct sockaddr_in addr;
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel;
int rc, exitcode;
rc = libssh2_init(0);
if(rc != 0)
{
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
return 1;
}
s_sock = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr = inet_addr(hostname);
if(setsockopt(s_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
{
perror("setsockopt failed\n");
}
if(setsockopt(s_sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
{
perror("setsockopt failed\n");
}
if(connect(s_sock, (struct sockaddr *)(&addr), sizeof(struct sockaddr_in)) != 0)
{
return -1;
}
session = libssh2_session_init();
if(!session)
{
return -1;
}
while((rc = libssh2_session_handshake(session, s_sock)) == LIBSSH2_ERROR_EAGAIN);
if(rc)
{
return -1;
}
while((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
if(rc)
{
goto shutdown;
}
while((channel = libssh2_channel_open_session(session)) == NULL && libssh2_session_last_error(session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN )
{
waitsocket(s_sock, session);
}
if(channel == NULL)
{
goto shutdown;
}
while((rc = libssh2_channel_exec(channel, custom_command)) == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(s_sock, session);
}
if(rc != 0)
{
goto shutdown;
}
for(;;)
{
int rc;
do
{
char command_output[65500];
rc = libssh2_channel_read(channel, command_output, sizeof(command_output));
if(rc > 0)
{
fprintf(stderr, "\nSuccessfully Login!\n \nuser:%s \npassword:%s \nhost:%s \nport:%d\n", username, password, hostname, port);
fprintf(stderr, "\nCommand output: %s\n", command_output);
goto shutdown;
}
else
{
if(rc != LIBSSH2_ERROR_EAGAIN)
{
goto shutdown;
}
}
}
while(rc > 0);
if(rc == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(s_sock, session);
}
else
{
break;
}
}
while((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(s_sock, session);
}
exitcode = 127;
if(rc == 0)
{
exitcode = libssh2_channel_get_exit_status(channel);
}
libssh2_channel_free(channel);
close(s_sock);
channel = NULL;
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
libssh2_exit();
exit(0);
shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
close(s_sock);
libssh2_exit();
return 0;
}
I have a simple client-server program implemented in C where a client can send integers to a server and the server replies with their sums. However, there is a troubling Segmentation fault (core dumped) shown on the server side whenever the client disconnects suddenly. The Client:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define PORT 5010
int main(int argc, char **argv) {
char buf[BUFSIZ], buf2[BUFSIZ], message[BUFSIZ], serverReply[BUFSIZ];
int SOCKET;
struct sockaddr_in server;
SOCKET = socket(AF_INET, SOCK_STREAM, 0);
if (SOCKET < 0) {
perror("Could not create socket");
return -1;
}
printf("Socket created\n");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
if (connect(SOCKET, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) {
perror("Could not connect");
return -1;
}
memset(&serverReply, 0, sizeof(serverReply));
printf("Connected to server.\nEnter first number: ");
scanf("%s", buf);
fflush(stdin);
printf("Enter second number: ");
scanf("%s", buf2);
strcat(buf, " ");
strcat(buf, buf2);
strcpy(message, buf);
if (send(SOCKET, message, strlen(message), 0) < 0) {
perror("Failed to send message");
return -1;
}
if (recv(SOCKET, serverReply, sizeof(serverReply), 0) < 0) {
perror("Could not receive message");
return -1;
}
printf("Server: %s", serverReply);
close(SOCKET);
}
The Server:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#define PORT 5010
int main(int argc, char *argv[]) {
char msg[BUFSIZ], reply[BUFSIZ];
struct sockaddr_in server, client;
int SOCKET, ACCEPT, READ, sockSize, num1, num2, option = 1, maxClients = 30,
h, clientSocket[maxClients], maxsd, sd, SELECT;
fd_set readfds;
for (h = 0; h < maxClients; h++) {
clientSocket[h] = 0;
}
SOCKET = socket(AF_INET, SOCK_STREAM, 0);
if (SOCKET == -1) {
perror("Could not create socket");
return -1;
}
if (setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) == -1) {
perror("Could not set OPTNAME");
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
printf("Created socket.\n");
if (bind(SOCKET, (struct sockaddr *) &server, sizeof(server)) < 0) {
perror("Could not bind");
return -1;
}
if (listen(SOCKET, 1) < 0) {
perror("Listen failed");
return -1;
}
printf("Server is listening.\n");
sockSize = sizeof(struct sockaddr_in);
while (1) {
FD_ZERO(&readfds);
FD_SET(SOCKET, &readfds);
maxsd = SOCKET;
for (h = 0; h < maxClients; h++) {
sd = clientSocket[h];
if (sd > 0) { FD_SET(sd, &readfds); }
if (sd > maxsd) { maxsd = sd; }
}
SELECT = select(maxsd + 1, &readfds, NULL, NULL, NULL);
if ((SELECT < 0) && (errno != EINTR)) {
perror("select error");
}
if (FD_ISSET(SOCKET, &readfds)) {
ACCEPT = accept(SOCKET, (struct sockaddr *) &server, (socklen_t *) &sockSize);
if (ACCEPT < 0) {
perror("Could not accept client");
return -1;
}
for (h = 0; h < maxClients; h++) {
if (clientSocket[h] == 0) {
clientSocket[h] = ACCEPT;
break;
}
}
printf("Client has joined the server.\n");
}
for (h = 0; h < maxClients; h++) {
sd = clientSocket[h];
if (FD_ISSET(sd, &readfds)) {
READ = read(sd, msg, sizeof(msg));
if (READ == -1) {
perror("Could not receive message");
return -1;
}
if (READ == 0) {
printf("Client disconnected\n");
fflush(stdout);
clientSocket[h]=0;
}
int e = 0;
char *p = strtok(msg, " ");
char *arr[2];
while (p != NULL) {
arr[e++] = p;
p = strtok(NULL, " ");
}
num1 = atoi(arr[0]);
num2 = atoi(arr[1]);
if ((strcmp(arr[0], "0") != 0 && num1 != 0) && (strcmp(arr[1], "0") != 0 && num2 != 0)) {
printf("Client: %d, %d\n", num1, num2);
sprintf(reply, "%d\n", num1 + num2);
if (write(sd, reply, strlen(reply)) < 0) {
perror("Could not send message");
return -1;
}
memset(&reply, 0, sizeof(reply));
} else {
printf("Conversion error");
strcpy(reply, "Conversion error.");
if (write(sd, reply, strlen(reply)) < 0) {
perror("Could not send message");
return -1;
}
}
}
}
}
}
How can the segfault be solved? How else can the codes be improved?
The segfault comes from the atoi function since NULL is received. Checking for NULL seems to do the trick...
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 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
int CreateSocket()
{
//pthread_attr_t attr;
// Socket creation for UDP
acceptSocket = socket(AF_INET,SOCK_DGRAM,0);
if(acceptSocket == -1)
{
printf("Failure: socket creation is failed, failure code\n");
return 1;
}
else
{
printf("Socket started!\n");
}
memset(&addr, 0, sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
rc=bind(acceptSocket,(struct sockaddr*)&addr,sizeof(addr));
fcntl(acceptSocket, O_NONBLOCK);
if(rc== -1)
{
printf("Oh dear, something went wrong with bind()! %s\n", strerror(errno));
return -1;
}
else
{
printf("Socket an port %d \n",port);
}
return acceptSocket;
}
int create_timer (void)
{
timer_t timer_id;
int timerfd = timer_create (CLOCK_REALTIME, 0, &timer_id);
if (timerfd < 0) {
perror ("timerfd_create:");
return -1;
}
return timerfd;
}
int start_timer_msec (int fd, int msec)
{
struct itimerspec timspec;
memset (&timspec, 0, sizeof(timspec));
timspec.it_value.tv_sec = 0;
timspec.it_value.tv_nsec = msec * 1000 * 1000;
if (timer_settime(fd, 0, &timspec, NULL) < 0) {
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
Xcp_Initialize();
int fd_2ms = create_timer();
int fd_10ms = create_timer();
int fd_100ms = create_timer();
int rval = 0;
if ((fd_2ms < 0) || (fd_10ms < 0) || (fd_100ms < 0)) {
exit (1);
}
if ((sock = CreateSocket()) < 0) {
perror ("Create_socket");
// fclose (fp);
exit (1);
}
start_timer_msec (fd_2ms, 2);
start_timer_msec (fd_10ms, 10);
start_timer_msec (fd_100ms, 100);
do
{
socklen_t len;
int max_fd = 0;
fd_set rdfds;
FD_ZERO (&rdfds);
GET_MAX_FD (max_fd, sock);
FD_SET (sock, &rdfds);
GET_MAX_FD (max_fd, fd_2ms);
FD_SET (fd_2ms, &rdfds);
GET_MAX_FD (max_fd, fd_10ms);
FD_SET (fd_10ms, &rdfds);
GET_MAX_FD (max_fd, fd_100ms);
FD_SET (fd_100ms, &rdfds);
rval = select (max_fd, &rdfds, NULL, NULL, NULL);
if (rval < 0) {
if (errno == EINTR)
continue;
} else if (rval > 0) {
/*Process CLI*/
if ((FD_ISSET (sock, &rdfds)))
{
FD_CLR(sock, &rdfds);
len = sizeof(client);
printf("NEW DATA ARRIVED\n");
//non blocking mode : MSG_DONTWAIT
rc=recvfrom(sock, buf, 256, 0, (struct sockaddr*) &client, &len);
//I am calculating the time here
//InterruptTime = GetTimeStamp();
//measurements[17] = InterruptTime;
if(rc==0)
{
printf("Server has no connection..\n");
break;
}
if(rc==-1)
{
if (errno == SIGINT)
continue;
printf("Oh dear, something went wrong with read()! %s\n", strerror(errno));
break;
}
ConfigureISR( );
XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );
}
if ((FD_ISSET (fd_2ms, &rdfds))) {
FD_CLR(fd_2ms, &rdfds);
TASK1(Task2ms_Raster);
start_timer_msec (fd_2ms, 2);
}
if ((FD_ISSET (fd_10ms, &rdfds))) {
FD_CLR(fd_10ms, &rdfds);
TASK2(Task10ms_Raster);
start_timer_msec (fd_10ms, 10);
}
if ((FD_ISSET (fd_100ms, &rdfds))) {
FD_CLR(fd_100ms, &rdfds);
TASK3(Task100ms_Raster);
start_timer_msec (fd_100ms, 100);
}
}
} while (1);
close(sock);
//fclose (fp);
return 0;
}
I created a socket to receive data from client via the ip address and port number. I created a timer to call the task for every 2ms, 10ms and 100ms. The above code is working fine for linux. But how to convert the above code for QNX RTOS. What are the changes should I make for QNX rtos. could some one please help me ??
IF I use the same code in qnx then it is crashing at int fd_2ms = create_timer(); !!