Using IPC Sys V - c

i have a server and a client and want to send a file from the client to the server, by using Sys V IPC. My Problem is the sending of the file, the server is creating the file but than stops at msgrcv_3 Invalid argument (last do while in the server). Maybe somebody have an idea.
Snippet of Server:
while(1){
int ausgabe=0;
/* Messageq */
if ((msqid = msgget(server_key, IPC_CREAT|IPC_EXCL|0666)) < 0){
perror("msgget_1");
exit(EXIT_FAILURE);
}
/* Message Empfangen */
if((msreturn = msgrcv(msqid, (void*)&name, sizeof(struct name),0,0))<0){
perror("msgrcv_1");
exit(EXIT_FAILURE);
}
result.exists = FileExists(name.file_name);
printf("%d\n", result.exists);
/* Message Versenden*/
if((msreturn = msgsnd(msqid, (void*)&result, sizeof(struct result),0))<0){
perror("msgsnd_1");
exit(EXIT_FAILURE);
}
if(result.exists == 42){
if((msreturn = msgrcv(msqid, (void*)&data, sizeof(struct data),0,0))<0){
perror("msgrcv_2");
exit(EXIT_FAILURE);
}
creatfile = open(data.file_name, O_WRONLY | O_CREAT| O_EXCL , 0);
if(creatfile == -1){
perror("creratfile");
exit(EXIT_FAILURE);
}
do{
if(msgrcv(msqid, (void*)&msg_body, sizeof(struct msg_body),0,0)<0){
perror("msgrcv_3");
exit(EXIT_FAILURE);
}
buff_blub = write(creatfile, &msg_body.buffer, msg_body.bufsize);
if (buff_blub < 0){
perror("write");
exit(EXIT_FAILURE);
}
ausgabe = ausgabe+msg_body.bufsize;
}
while(ausgabe != data.datasize);
chmod(data.file_name, 0644);
}
}
Snippet of the Client:
strncpy(name.file_name, argv[2], sizeof(name.file_name) - 1);
/* Message Versenden*/
if((msreturn = msgsnd(msqid, (void*)&name, sizeof(struct name),0))<0){
perror("msgsnd");
exit(EXIT_FAILURE);
}
/* Message Empfangen */
if((msreturn = msgrcv(msqid, (void*)&result, sizeof(struct result),0,0))<0){
perror("msgrcv");
exit(EXIT_FAILURE);
}
if(result.exists == 1){
puts("File already exists");
exit(EXIT_FAILURE);
}
else if(result.exists == 42){
file_read = open(argv[1], O_RDONLY);
if (file_read > 0){
if (fstat(file_read, &sb)==-1){
perror("fstat");
return EXIT_FAILURE;
}
strncpy(data.file_name, argv[2], sizeof(data.file_name) - 1);
data.datasize = sb.st_size;
data.c_pid = getpid();
if((msreturn = msgsnd(msqid, (void*)&data, sizeof(struct data),0))<0){
perror("msgsnd");
exit(EXIT_FAILURE);
}
while((file_buffer = read (file_read, &msg_body.buffer, BUF_SIZE)) > 0){
msg_body.bufsize = file_buffer;
msg_body.prio = 2;
if((msreturn = msgsnd(msqid, (void*)&msg_body, sizeof(struct msg_body),0))<0){
perror("msgsnd");
exit(EXIT_FAILURE);
}
}
close(file_read);
}
}
return 1;
}
the structur:
#include <unistd.h>
#if !defined(__MSGBSP_H)
#define __MSGBSP_H
#define BUF_SIZE 1024
struct data {
char file_name[255];
ssize_t datasize;
long c_pid;
};
struct name {
char file_name[255];
};
struct result {
int exists;
};
struct header {
int size;
};
struct msg_body {
long prio;
ssize_t bufsize;
char buffer[BUF_SIZE];
};
#endif

Related

C Socket program doesn't print desired output (No Error)

I can't seem to print what I enter in my client. I have compiled both without any error. Can't figure out why it isn't printing the desired output.
Q. What is wrong with my code ? How can I print a string with whitespaces through the client in the server.
Here is the code for the server.
/* Server Side program */
int sid,nid;
struct sockaddr_in q;
char x[100];
int len=sizeof(struct sockaddr_in);
sid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
q.sin_family=PF_INET;
q.sin_port=1600;
q.sin_addr.s_addr=0;
bind(sid,&q,len);
listen(sid,20);
while(1)
{
memset(x,0,sizeof(x));
nid=accept(sid,&q,&len);
read(nid,x,100);
printf("%s\n",x);
}
Here is the code for the client.
/*client side program*/
int sid,status;
struct sockaddr_in q;
int len=sizeof(struct sockaddr_in);
char x[100];
sid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
q.sin_family=PF_INET;
q.sin_port=1600;
q.sin_addr.s_addr=0;
status=connect(sid,&q,len);
if(status==-1)
{
printf("Connection failure");
exit(0);
}
while(1)
{
printf("Enter string to send : ");
scanf("%[^\n]s",x);
write(sid,x,strlen(x));
if(strcmp(x,"bye")==0)
break;
}
There is all kinds of problems with your code. Lack of error handling. Incorrect use of printf() and scanf(). Resource leaks.
Try something more like this instead:
Server:
int main()
{
int sid, nid;
struct sockaddr_in q;
char x[100];
socklen_t qlen;
ssize_t xlen;
sid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sid < 0)
{
perror("socket failure");
return -1;
}
q.sin_family = AF_INET;
q.sin_port = htons(1600);
q.sin_addr.s_addr = INADDR_ANY;
if (bind(sid, &q, sizeof(q)) < 0)
{
perror("bind failure");
return -1;
}
if (listen(sid, 20) < 0)
{
perror("listen failure");
return -1;
}
while(1)
{
qlen = sizeof(q);
nid = accept(sid, &q, &qlen);
if (nid < 0)
{
perror("accept failure");
return -1;
}
while ((xlen = read(nid, x, sizeof(x))) > 0)
{
printf("Received: '%.*s'\n", xlen, x);
}
if (xlen < 0)
perror("read failure");
else
printf("client disconnected\n");
close(nid);
}
return 0;
}
Client:
int main()
{
int sid, xlen;
struct sockaddr_in q;
char x[100];
sid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sid < 0)
{
perror("socket failure");
return -1;
}
q.sin_family = AF_INET;
q.sin_port = htons(1600);
q.sin_addr.s_addr = inet_addr("server ip here"); // or INADDR_LOOPBACK (127.0.0.1)
if (connect(sid, &q, sizeof(q)) < 0)
{
printf("connect failure");
return -1;
}
while(1)
{
printf("Enter string to send : ");
if (!fgets(x, sizeof(x), stdin))
break;
xlen = strlen(x);
if ((xlen > 0) && (x[xlen-1] == '\n'))
{
x[xlen-1] = '\0';
--xlen;
}
if (write(sid, x, xlen) < 0)
{
perror("write failure");
break;
}
if (strcmp(x, "bye") == 0)
break;
}
close(sid);
return 0;
}

Create HTTP GET in C return 301 redirect using IP address

I want to send a GET request to a page and retrieve it to use later to a crawler
I have implemented my own D.N.S. resolver (like DIG command in LINUX) and I want to use the ip address to get the http page
I have the following code
typedef struct http_request
{
request_type req_type;
char* ip;
int port_number;
char* path;
char* data;
char* hostname;
}http_request;
typedef struct http_response
{
char* raw_response;
int status_code;
char* status_text;
char* body;
char* server_name;
int content_length;
char* content_type;
}http_response;
// main method
http_response* send_http_request(http_request* request) {
if (request == NULL) {
printf("HTTP request is NULL.\n");
return NULL;
}
http_response* response = (http_response*) malloc(sizeof(http_response));
if (response == NULL) {
exit(1);
return NULL;
}
char http_request_buffer[REQUEST_BUFF_SIZE];
memset(http_request_buffer, 0, REQUEST_BUFF_SIZE);
sprintf(http_request_buffer, "GET /%s HTTP/1.1\r\nHost:%s\r\n\r\n",
request->path, request->ip);
process_http_request(request, http_request_buffer, response);
return response;
}
static int process_http_request(http_request* request,
char* http_request_buffer, http_response* response) {
int socketfd;
struct sockaddr_in socket_details;
char temp_buffer[TEMP_BUFF_SIZE];
char* http_response_buffer;
ssize_t bytes_sent = 0;
ssize_t total_bytes_sent = 0;
ssize_t bytes_received = 0;
ssize_t total_bytes_received = 0;
int status;
http_response_buffer = (char*) malloc(RESPONSE_BUFF_SIZE);
if (http_response_buffer == NULL) {
printf(
"process_http_request: memory allocation failed for response buffer.\n");
return HTTP_ERROR_MEM_ALLOC_FAILED;
}
memset(http_response_buffer, 0, RESPONSE_BUFF_SIZE);
socketfd = socket(AF_INET, SOCK_STREAM, 0);
if (socketfd == -1) {
printf("process_http_request: socket creation failed.\n");
return HTTP_ERROR_SOCKET_CREATION_FAILED;
}
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
if (setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout,
sizeof(timeout)) < 0)
printf("process_http_request: socket option setting failed.\n");
bzero(&socket_details, sizeof(socket_details));
socket_details.sin_family = AF_INET;
socket_details.sin_addr.s_addr = inet_addr(request->ip);
socket_details.sin_port = htons(request->port_number);
if (connect(socketfd, (struct sockaddr*) &socket_details,
sizeof(struct sockaddr)) == -1) {
printf("process_http_request: Could not connect to the server.\n");
return HTTP_ERROR_SERVER_CONN_FAILED;
}
while (1) {
bytes_sent = send(socketfd, http_request_buffer,
strlen(http_request_buffer), 0);
if (bytes_sent < 0) {
printf("process_http_request: error writing on socket\n");
close(socketfd);
return HTTP_ERROR_SOCKET_WRITE_FAILED;
} else {
printf(
"process_http_request: wrote %d bytes data on socket successfully.\n",
(int) bytes_sent);
}
total_bytes_sent += (int) bytes_sent;
printf("process_http_request: total bytes sent = %d\n",
(int) total_bytes_sent);
if (total_bytes_sent == strlen(http_request_buffer))
break;
}
while (1) {
printf("process_http_request: receiving bytes from server\n");
memset(temp_buffer, 0, TEMP_BUFF_SIZE);
bytes_received = recv(socketfd, temp_buffer, TEMP_BUFF_SIZE, 0);
if (bytes_received == -1) {
if (total_bytes_received == 0) {
printf(
"process_http_request: Data could not be received from socket.\n");
close(socketfd);
return HTTP_ERROR_REC_FAILED;
} else {
printf(
"process_http_request: Timeout waiting for more data.\n");
break;
}
} else if (bytes_received > 0) {
sprintf(http_response_buffer, "%s%s", http_response_buffer,
temp_buffer);
total_bytes_received += bytes_received;
printf("process_http_request: total bytes received = %d\n",
(int) total_bytes_received);
}
if (bytes_received == 0) {
printf("process_http_request: Data receiving finished.\n");
close(socketfd);
break;
}
}
printf("raw buffer=%s", http_response_buffer);
response->raw_response = http_response_buffer;
status = process_http_response(http_response_buffer, response);
if (status == SUCCESS)
printf("process_http_request: HTTP response parsed successfully.\n");
else
printf(
"process_http_request: HTTP response parsing encountered problem. \n");
return status;
}
The problem is that in almost all cases return me a page with 301 redirect and a link .For example for google's ip return me a redirect page to http://www.google.com/ , and I want the page itself and I don't know what to do.
Someone please help.Thank you!

C written HTTP server resets connection after repling

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

Socket select don't work

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);

what are the changes from the linux code to qnx code?

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(); !!

Resources