Usage of htonl() and ntonhl() for unsigned char - c

I am pasting my client and server code below. My program is running fine, except that i am trying to send an ipaddress in my src and dest field, and for some reason, even though i am sending it as 131.199.166.232, it is printing as 232.166.199.131. But rest of my packet values are printed in a proper way. I have used memcpy(), so I feel its a memcpy thing, which somewhere I did wrong, but in Beej's guide as there is a section # the byte ordering in different computer architectures.....I have not used htonl() and all, so maybe it is because of that.Please guide me as where I am going wrong. Also kindly tell me the way i am sending data, how should the htonl() function can be used in my code....Thanks in advance.
Client:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define MAXPROFILES 2
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
unsigned char buf[1024];
unsigned int srcAddress = 2193598184;
unsigned int destAddress = 2193598182;
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
typedef struct profile_datagram_t
{
unsigned char src[4];
unsigned char dst[4];
unsigned char ver;
unsigned char n;
struct profile_t profiles[MAXPROFILES];
} header;
header outObj;
int j =0;
int i =0;
// for loop for doing the malloc so that we can allocate memory to all profiles
for(i=0;i<MAXPROFILES;i++){
outObj.profiles[i].data = malloc(5);
}
for(i=3;i>=0;i--){
outObj.src[i] = (srcAddress >> (i*8)) & 0xFF;
outObj.dst[i] = (destAddress >> (i*8)) & 0xFF;
printf("%d",outObj.src[i]);
}
outObj.ver = 1;
outObj.n = 2;
memcpy(buf,&outObj.src,4);
memcpy(buf+4,&outObj.dst,4);
memcpy(buf+8,&outObj.ver,1);
memcpy(buf+9,&outObj.n,1);
outObj.profiles[0].length = 5;
outObj.profiles[0].type = 1;
outObj.profiles[1].length = 5;
outObj.profiles[1].type = 2;
for(i=0;i<MAXPROFILES;i++){
for(j=0;j<5;j++){
outObj.profiles[i].data[j] = j+1;
}
}
int k = 10;
// for loop to do memcopy of length,type and data.
for(i=0;i<MAXPROFILES;i++){
memcpy(buf+k,&outObj.profiles[0].length,1);
memcpy(buf+k+1,&outObj.profiles[0].type,1);
memcpy(buf+k+2,outObj.profiles[0].data,5);
k +=7;
}
if (argc < 3) {
fprintf(stderr,"usage: %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]); //Convert ASCII to integer
sockfd = socket(AF_INET, SOCK_STREAM, 0); // socket file descriptor
if (sockfd < 0)
error("ERROR DETECTED !!! Problem in opening socket\n");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR DETECTED !!!, no such server found \n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr)); //clear the memory for server address
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
printf("Client 1 trying to connect with server host %s on port %d\n", argv[1], portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR in connection");
printf("SUCCESS !!! Connection established \n");
if (write(sockfd, buf, k) < 0)
{
error("Write error has occured ");
}
return 0;
Server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAXPROFILES 2
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
struct sockaddr_in serv_addr, cli_addr;
unsigned char buf[1024];
int my_data2[10] = {1,3,9,10};
int my_data[10] = {1,2,3,4,5};
int myDataBinary[500] = {0};
int myDataBinary2[500] = {0};
int recData[500] = {0};
int index1=0;
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
typedef struct profile_datagram_t
{
unsigned char src[4];
unsigned char dst[4];
unsigned char ver;
unsigned char n;
struct profile_t profiles[MAXPROFILES];
} header;
header outObj;
int j =0;
int i =0;
if (argc < 2) {
fprintf(stderr,"usage: %s port_number1",argv[0]);
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR DETECTED !!! Problem in opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR DETECTED !!! There was a problem in binding");
listen(sockfd, 10);
clilen = sizeof(cli_addr);
printf("Server listening on port number %d...\n", serv_addr.sin_port);
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR DETECTED !!! the connection request was not accepted");
int rc = read(newsockfd,buf,100);
if(rc < 0){
printf("error");
}
else {
printf("success %d",rc);
}
memcpy(&outObj.src,buf+0,4);
memcpy(&outObj.dst,buf+4,4);
memcpy(&outObj.ver,buf+8,1);
memcpy(&outObj.n,buf+9,1);
printf("\nsrc ip = ");
for(int i=0;i<4;i++){
printf("%d ",outObj.src[i]);
}
printf("\ndest ip = ");
for(int i=0;i<4;i++){
printf("%d ",outObj.src[i]);
}
printf("\nversion = %d",outObj.ver);
printf("\nnumber = %d",outObj.n);
int k = 10;
for(i=0;i<outObj.n;i++){
memcpy(&outObj.profiles[i].length,buf+k,1);
memcpy(&outObj.profiles[i].type,buf+k+1,1);
outObj.profiles[i].data = malloc(outObj.profiles[i].length);
memcpy(outObj.profiles[i].data,buf+k+2,5);
k +=7;
}
for(int i=0;i<outObj.n;i++){
printf("\nMessage %d :",i+1);
printf("\nLength : %d",outObj.profiles[i].length);
printf("\nType : %d",outObj.profiles[i].type);
for(int j=0;j<5;j++){
printf("\ndata %d : %d",j,outObj.profiles[i].data[j]);
}
}
for(int i=0; i<sizeof(my_data)/sizeof(int);i++)
{
if(my_data[i] > 0){
index1 = my_data[i];
myDataBinary[index1] = 1;
printf("my data %d = %d\n",index1,myDataBinary[index1]);
}
}
for(int i=0; i<sizeof(my_data2)/sizeof(int);i++)
{
if(my_data2[i] > 0){
index1 = my_data2[i];
myDataBinary2[index1] = 1;
printf("my data %d = %d\n",index1,myDataBinary2[index1]);
}
}
int sumRecievedData = 0;
int sumMyData = 0;
int sumMultpliedData = 0;
float Cov =0;
float sdMyData = 0;
float sdRecievedData =0;
int n = 500;
float rho;
for(int i=0;i<outObj.n;i++){
index1=0;
for (int j=0; j<outObj.profiles[i].length;j++) {
if(outObj.profiles[i].data[j] > 0){
index1 = outObj.profiles[i].data[j];
recData[index1] = 1;
printf("rec data %d = %d\n",index1,recData[index1]);
}
}
}
return 0;
}

an ip address is really just an array of unsigned char.
uchar ip[] = {127,0,0,1};
Is a fine representation for a loopback address. But an array of four bytes, and a int really aren't that large; with one exception endiannes! So suppose I create the int which represents that ip. A naive approach might be:
int ip = (127<<24)|(0<<16)|(0<<8)|(1)
Of course, on little endian machines, like the x86 and arm it doing this:
char *char_ip = (void*)&ip;
and iterating over that aray would yield:
1, 0, 0, 127
But on a big endian machine, like a PowerPC, or a SPARC, we would have what we expect,
127, 0, 0, 1
Big endian is also known as "network byte order" which is what the n in htonl stands for: "host to network long". These functions are frequently used when reading or writing integers over the network. Suppose a server wants to send a client some number:
uint32_t important = htonl(42);
write(client, &important, sizeof important);
Then, to read it, the client goes:
uint32_t important;
read(server, &important, sizeof important);
important = ntohl(important);
The reason your ip address were flipped was because ip addresses are expected to be in network byte order, but yours were little endian instead. htonl on an int-type ip will flip it for you.

This is way too much code for me to read, but if you just want to create a byte array for serializing, you don't need any special functions at all, you can just write it algebraically:
unsigned char buf[sizeof(uint_type)];
uint_type value;
for (size_t i = 0; i != sizeof(uint_type); ++i)
{
// Little-endian
buf[i] = value >> (i * CHAR_BIT);
// Big-endian
buf[sizeof(uint_type - i - 1)] = value >> (i * CHAR_BIT);
}
Note that this code is independent of your system's endianness.
Since you asked, the htonl/ntohl functions are for dealing with uint32_t integers directly, without explicit char arrays:
uint32_t value;
myfile.read((char*)&value, sizeof(value)); // network endianness
value = ntohl(value); // host endianness
/* fiddle fiddle */
value = htonl(value);
yourfile.write((const char*)&value, sizeof(value));
(More typically you'd be writing to a socket rather than a file, I suppose.)

Related

Segmentation fault (core dumped) from command line argument

I'm trying to run some code from terminal using arguments. Here's my code:
int PORT_NUM = 0;
int BYTES_TO_SEND = 0;
char* LocalAddresss = "";
char* concat(char *s1, char *s2)
{
char *result = malloc(strlen(s1)+strlen(s2)+1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
char data[BYTES_TO_SEND];
LocalAddresss = concat("192.168.1.",argv[1]);
PORT_NUM = atoi(argv[2]);
BYTES_TO_SEND = atoi(argv[3]);
fflush(stdout);
for(int i = 0; i < BYTES_TO_SEND; i++){
data[i] = 'Z';
}
char* message_to_send = data;
portno = PORT_NUM;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(LocalAddresss);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
while(1){
n = write(sockfd,message_to_send,strlen(message_to_send));
}
close(sockfd);
return 0;
}
My issue is this. The following works: ./TCP_client 16 2000 100 on the command line.
This doesn't: ./TCP_client 16 2000 3000
I get "Segmentation fault (core dumped)"
Are there restrictions on the number of total bytes in command line arguments or something? How can I resolve this issue?
After running this with GDB it says "Program received signal SIGBUS, Bus error.0x0000000100000ccf in main ()" Not really sure what this is though.
this fails becuase you are declaring data with a size of 0
int BYTES_TO_SEND = 0;
...
char data[BYTES_TO_SEND];
'''
LocalAddresss = concat("192.168.1.",argv[1]);
PORT_NUM = atoi(argv[2]);
BYTES_TO_SEND = atoi(argv[3]);
you need to move the lines around
int BYTES_TO_SEND = 0;
...
LocalAddresss = concat("192.168.1.",argv[1]);
PORT_NUM = atoi(argv[2]);
BYTES_TO_SEND = atoi(argv[3]);
char data[BYTES_TO_SEND];
'''
but this is a bad plan - putting a big buffer like that on the stack, better to malloc it. Your example will work, but its not a good design
If i were you i would use from the string.h library the strcat() function.
#include <string.h>
...
char LocalAddresss[15] = "192.168.1.";
strcat(LocalAddress, argv[1]);

variable length message over tcp

I am trying to send variable length message in TCP but the message length that
is printed is always 0. I am using beej guide code for send and receive and pack and unpack to send the header length.Can someone please point out the mistake.
server code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAX_SIZE 50
void error(const char *msg)
{
perror(msg);
exit(1);
}
void packi32(unsigned char *buf, unsigned long i)//from beej guide
{
*buf++ = i>>24; *buf++ = i>>16;
*buf++ = i>>8; *buf++ = i;
}
/* sends all data - thanks to Beej's Guide to Network Programming */
int sendall(int s, char *buf, int *len)
{
int total=0;
int bytesleft=*len;
int n=0;
/* send all the data */
while(total<*len){
/* send some data */
n=send(s,buf+total,bytesleft,0);
/* break on error */
if(n==-1)
break;
/* apply bytes we sent */
total+=n;
bytesleft-=n;
}
/* return number of bytes actually send here */
*len=total;
/* return -1 on failure, 0 on success */
return n==-1?-1:0;
}
int sendus(int s,char *msg)
{
char buf[4];//here 4 is header length
int len = strlen(msg);
packi32(buf,len);
int ll = 4;// ll is header length containing message length
int x;
if((x = sendall(s,buf,&ll))< 0)
printf("value of sent x %d\n",x);
int y = sendall(s,msg,&len);
return y;
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2)
{
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
char msg[1024] = "hello";
int xx = sendus(sockfd,(char*)msg);
close(newsockfd);
close(sockfd);
return 0;
}
client code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include<errno.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
/** unpacki32() -- unpack a 32-bit int from a char buffer (like ntohl())
*/
unsigned long unpacki32(unsigned char *buf)
{
return (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
}
/* receives all data - modelled after sendall() */
int recvall(int s, char *buf, int *len, int timeout){
int total=0;
int bytesleft=*len;
int n=0;
time_t start_time;
time_t current_time;
/* clear the receive buffer */
bzero(buf,*len);
time(&start_time);
/* receive all data */
while(total<*len){
/* receive some data */
n=recv(s,buf+total,bytesleft,0);
/* no data has arrived yet (non-blocking socket) */
if(n==-1 && errno==EAGAIN){
time(&current_time);
if(current_time-start_time>timeout)
break;
sleep(1);
continue;
}
/* receive error or client disconnect */
else if(n<=0)
break;
/* apply bytes we received */
total+=n;
bytesleft-=n;
}
/* return number of bytes actually received here */
*len=total;
/* return <=0 on failure, bytes received on success */
return (n<=0)?n:total;
}
int recvme(int s, char *buf)
{
char len[4];
int l = 4;
int n = recvall(s,len,&l,10);
int msg_len = unpacki32(len);
printf("msg_length :%d",msg_len);
int z ;
z = recvall(s,buf,&msg_len,10);
return z;
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[1024];
if (argc < 3)
{
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL)
{
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
n = recvme(sockfd, buffer);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
}
The basic cause for the failure is in the server's line
int xx = sendus(sockfd,(char*)msg);
- sockfd is the listen() socket, but we have to use the newsockfd returned from accept(), i. e.
sendus(newsockfd, msg);

Sending Data in socket programming using "C"

I had earlier posted a question, regarding same, but over here i want guidance for my code. Using the tips from people I have tried to create for sending a packet. My max packet structure alongwith header and payload is of 16 bytes.Kindly if possible glance through the sending and receiving code and suggest where i am going wrong. Basically my client keeps sending data to server,it just doesn't end and server doesn't show results.
Client:
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
struct packet
{
long int srcID;
long int destID;
long int pver;
long int profiles;
char length;
long int data;
};
if (argc < 3) {
fprintf(stderr,"usage: %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]); //Convert ASCII to integer
sockfd = socket(AF_INET, SOCK_STREAM, 0); // socket file descriptor
if (sockfd < 0)
error("ERROR DETECTED !!! Problem in opening socket\n");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR DETECTED !!!, no such server found \n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr)); //clear the memory for server address
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
printf("Client 1 trying to connect with server host %s on port %d\n", argv[1], portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR in connection");
printf("SUCCESS !!! Connection established \n");
char buffer[128];
struct packet *pkt = (struct packet *) buffer;
char *payload = buffer + sizeof(struct packet);
long int packet_size;
printf("Started Creating packet\n");
pkt->srcID = 0x01;
pkt->destID = 0x02;
pkt->pver = 0x01;
pkt->profiles = 0x01;
pkt->length = 128;
pkt->data = 1; 2; 3; 4; 5; 6; 7; 8;
if (send(sockfd,pkt,sizeof(packet_size),0) <0)
printf ("error\n");
else
printf ("packet send done");
return 0;
}
Server:
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
struct sockaddr_in serv_addr, cli_addr;
int n;
char wish;
long int SrcID;
long int DestID;
long int Pver;
long int Profiles;
long int Data;
char Length;
char bytes_to_receive;
char received_bytes;
struct packet
{
long int srcID;
long int destID;
long int pver;
long int profiles;
char length;
long int data;
};
if (argc < 2) {
fprintf(stderr,"usage: %s port_number1",argv[0]);
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR DETECTED !!! Problem in opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR DETECTED !!! There was a problem in binding");
listen(sockfd, 10);
clilen = sizeof(cli_addr);
printf("Server listening on port number %d...\n", serv_addr.sin_port);
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR DETECTED !!! the connection request was not accepted");
char buffer[128];
struct packet *pkt = (struct packet *) buffer;
char *payload = buffer + sizeof(struct packet);
long int packet_size;
bytes_to_receive = sizeof(pkt);
received_bytes = 0;
if (recv(newsockfd, pkt, sizeof(pkt), 0) < 0)
error("ERROR DETECTED !!! There was a problem in reading the data");
else
{
do {
received_bytes += (buffer + received_bytes, bytes_to_receive - received_bytes);
} while (received_bytes != bytes_to_receive);
SrcID = pkt->srcID;
DestID = pkt->destID;
Pver = pkt->pver ;
Profiles = pkt->profiles;
Length = pkt->length;
Data = pkt->data;
printf("Data Received from Client_1 are :\n");
printf("Source ID: %l\n", SrcID);
printf("Destination ID: %l\n", DestID);
printf("profile Version: %l\n", Pver);
printf("No of Profiles: %l\n", Profiles);
printf("Length: %l\n", Length);
printf("data : %l\n", Data);
}
if (close(newsockfd) == -1) {
error("Error closing connection with client 1");
}
printf("Connection with client 1 has been closed\n");
return 0;
}
The server is not showing any o/p. Client says it has send the packet. While compiling the server code i see four warnings saying unknown conversion type characters 0xa in format for all the printf statements in server code. I guess I am going wrong somewhere in the server code side, but I am not able to follow the "serialization". Please update me with your inputs, it would be of great help.
Here is couple of issues that I found:
Your client keep sending packages because it is in infinite while
loop.
You passed wrong len parameter of recv function. Right now
you pass sizeof(packet_size) which is equal to sizeof(long int) (4
bytes on 32 bit OS), but probably your intension was to use
sizeof(packet) (16 bytes).
You don't check how many bytes were
truly read by recv function. With TCP you don't have guaranties that
you read all 16 bytes of struct packet. So from time to time you
could read less bytes and your packet will be incomplete. Here is an
example in some pseudo code how you should receive whole packet:
bytes_to_receive = sizeof(packet)
received_bytes = 0;
do {
received_bytes += recv(buffer + received_bytes, bytes_to_receive - received_bytes)
} while (received_bytes != bytes_to_receive)
Your struct packet in client and server is different. In one you use char length; in second long int length;
I think also this kind of assignments in server make no sense pkt->srcID = SrcID; and should be something like this SrcID = pkt->srcID;
The problem with the client continually sending is because you simply have it in a loop. With indentation fixed, it becomes clear what has happened:
while (1)
{
if (send(sockfd,pkt,sizeof(packet_size),0) <0)
printf ("error\n");
else
printf ("packet send done");
}
addr_size = sizeof serverAddr;
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);

How do I run my server as a daemon process?

For a few days I have been trying to run my server as a daemon process that runs continuously. Right now, my server closes the connection with the client and then closes itself. So I am able to send my packet once to the server, but when I try to send it again I get a segmentation fault error.
Also, even though I wrote the daemon process, I am not sure about its behavior and whether it is working or not.
Server Code:
#include <sys/socket.h>
#include <netinet/in.h>
#include "unistd.h"
#include <syslog.h>
#include <math.h>
#define MAXPROFILES 2
float Pearson(int mySum, int recSum, int multSum);
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
struct sockaddr_in serv_addr, cli_addr;
unsigned char buf[1024];
int myDataBinary[500] = {0};
int myDataBinary2[500] = {0};
int recData[500] = {0};*/
int index1=0;
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
typedef struct profile_datagram_t
{
unsigned char *src;
unsigned char *dst;
unsigned char ver;
unsigned char n;
struct profile_t profiles[MAXPROFILES];
} header;
header outObj;
int j =0;
int i =0;
extern int daemon_proc; /* defined in error.c */
void daemon_init (const char *pname, int facility)
{
/* Our process ID and Session ID */
pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
/* Open any logs here */
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0) {
/* Log the failure */
exit(EXIT_FAILURE);
}
/* Change the current working directory */
if ((chdir("/")) < 0) {
/* Log the failure */
exit(EXIT_FAILURE);
}
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
/* Daemon-specific initialization goes here */
}
if (argc < 2) {
fprintf(stderr,"usage: %s port_number1",argv[0]);
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR DETECTED !!! Problem in opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR DETECTED !!! There was a problem in binding");
listen(sockfd, 10);
clilen = sizeof(cli_addr);
while (1){
printf("Server listening on port number %d...\n", serv_addr.sin_port);
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR DETECTED !!! the connection request was not accepted");
int rc = read(newsockfd,buf,100);
if(rc < 0){
printf("error");
}
else {
printf("success %d",rc);
}
outObj.src = malloc(4);
outObj.dst = malloc(4);
// printf(pointer);
memcpy(outObj.src,buf+0,4);
memcpy(outObj.dst,buf+4,4);
memcpy(&outObj.ver,buf+8,1);
memcpy(&outObj.n,buf+9,1);
printf("\nSource IP = ");
for(int i=0;i<4;i++){
printf("%d ",outObj.src[i]);
}
printf("\nDestination IP = ");
for(int i=0;i<4;i++){
printf("%d ",outObj.dst[i]);
}
printf("\nVersion = %d",outObj.ver);
printf("\nNumber of messages = %d",outObj.n);
int k = 10;
for(i=0;i<outObj.n;i++){
memcpy(&outObj.profiles[i].length,buf+k,1);
memcpy(&outObj.profiles[i].type,buf+k+1,1);
outObj.profiles[i].data = malloc(outObj.profiles[i].length);
memcpy(outObj.profiles[i].data,buf+k+2,5);
k +=7;
}
for(int i=0;i<outObj.n;i++){
printf("\n------- Message %d --------",i+1);
printf("\nLength : %d",outObj.profiles[i].length);
printf("\nType : %d\n",outObj.profiles[i].type);
for(int j=0;j<5;j++){
printf(" Data[%d] : %d",j,outObj.profiles[i].data[j]);
}
}
float rho;
for(int i=0;i<outObj.n;i++){
printf("\n\n---------- Values for Data Profile %d ------------",i+1);
index1=0;
int sumRecievedData = 0;
int sumMyData = 0;
int sumMultpliedData = 0;
int my_data[10] = {0};// = {1,2,3,4,5};
int myDataBinary[500] = {0};
int recData[500] = {0};
if(i==0){
my_data[0] = 1;
my_data[1] = 3;
my_data[2] = 9;
my_data[3] = 10;
} else if(i==1){
my_data[0] = 1;
my_data[1] = 2;
my_data[2] = 3;
my_data[3] = 4;
my_data[4] = 5;
}
for(int i=0; i<sizeof(my_data)/sizeof(int);i++)
{
if(my_data[i] > 0){
index1 = my_data[i];
myDataBinary[index1] = 1;
//printf("my data %d = %d\n",index1,myDataBinary[index1]);
}
}
for (int j=0; j<outObj.profiles[i].length;j++) {
if(outObj.profiles[i].data[j] > 0){
index1 = outObj.profiles[i].data[j];
recData[index1] = 1;
//printf("rec data %d = %d\n",index1,recData[index1]);
}
}
for(int i=0;i<500;i++){
sumRecievedData += recData[i];
sumMyData += myDataBinary[i];
sumMultpliedData += recData[i] * myDataBinary[i];
}
printf("\nrecSum = %d, \nmySum = %d, \nmultSum = %d\n",sumRecievedData,sumMyData,sumMultpliedData);
rho = Pearson(sumMyData,sumRecievedData,sumMultpliedData);
printf("\nPearson Coefficient for Data Profile %d= %f\n",i+1,rho);
}
return 0;
}
//exit(EXIT_SUCCESS);
}
float Pearson(int mySum, int recSum, int multSum)
{
float Cov =0;
float sdMyData = 0;
float sdRecievedData =0;
float rho;
int n = 500;
Cov = (1.0/(n-1))*(multSum - (1.0/n)*mySum*recSum);
sdMyData = sqrt((1.0/(n-1))*(mySum - (1.0/n)*mySum*mySum));
sdRecievedData = sqrt((1.0/(n-1))*(recSum - (1.0/n)*recSum*recSum));
printf("\nCovariance = %f, \nVarianceMyData = %f, \nVarianceRecData = %f",Cov,sdMyData,sdRecievedData);
if (sdMyData == 0.0 || sdRecievedData == 0.0){
rho = 0.0;
}else{
rho = Cov/(sdMyData*sdRecievedData);
}
return(rho);
}
The server does return(0); at the bottom of the supposedly infinite loop, thus exiting from main() and terminating.
As noted in a comment, your code includes a nested function daemon_init() which is never called. Nested functions are a GCC-only feature; you should avoid using them. If you do call it, the server is going to have problems because it closes stdout and stderr but your code then tries to write to the now closed files.
Without the client code, it is very far from clear what information is being sent over the wire. There is one read() call:
int rc = read(newsockfd,buf,100);
That should be using sizeof(buf) in place of 100; and it is wasteful to use char buf[1024]; when you only use 100 bytes. You check that you got some data; you do not check that you got all the data you expect. You might, therefore, be reading uninitialized data.
There are numerous other similar problems in the code, especially with constants used somewhat inappropriately. As also noted in a comment, the code is not properly modularized.
The code does not seem to respond to the client; its outputs only go to its standard output (or error).
This code compiles reasonably cleanly, but still doesn't call daemon_init() for the reasons mentioned earlier.
#include <errno.h>
#include <math.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h> /* exit() */
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h> /* umask() */
#include <syslog.h>
#include <unistd.h>
#define MAXPROFILES 2
static void error(const char *fmt, ...)
{
va_list args;
int errnum = errno;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, ": %d %s\n", errnum, strerror(errnum));
exit(1);
}
static float Pearson(int mySum, int recSum, int multSum);
static void daemon_init(void)
{
/* Our process ID and Session ID */
pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0)
error("failed to fork");
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0)
exit(EXIT_SUCCESS);
/* Change the file mode mask */
umask(0);
/* Open any logs here */
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0)
error("failed to set session ID");
/* Change the current working directory */
if ((chdir("/")) < 0)
error("failed to chdir to root");
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
/* Daemon-specific initialization goes here */
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
unsigned char buf[1024];
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
typedef struct profile_datagram_t
{
unsigned char *src;
unsigned char *dst;
unsigned char ver;
unsigned char n;
struct profile_t profiles[MAXPROFILES];
} header;
header outObj;
if (argc != 2)
error("usage: %s port", argv[0]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR DETECTED !!! Problem in opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR DETECTED !!! There was a problem in binding");
listen(sockfd, 10);
while (1)
{
clilen = sizeof(cli_addr);
printf("Server listening on port number %d...\n", serv_addr.sin_port);
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR DETECTED !!! the connection request was not accepted");
int rc = read(newsockfd,buf,100);
if (rc < 0)
error("read error");
else
printf("read: success %d", rc);
outObj.src = malloc(4);
outObj.dst = malloc(4);
// printf(pointer);
memcpy(outObj.src,buf+0,4);
memcpy(outObj.dst,buf+4,4);
memcpy(&outObj.ver,buf+8,1);
memcpy(&outObj.n,buf+9,1);
printf("\nSource IP = ");
for (int i=0;i<4;i++)
printf("%d ",outObj.src[i]);
printf("\nDestination IP = ");
for (int i=0;i<4;i++)
printf("%d ",outObj.dst[i]);
printf("\nVersion = %d",outObj.ver);
printf("\nNumber of messages = %d",outObj.n);
int k = 10;
for (int i=0;i<outObj.n;i++)
{
memcpy(&outObj.profiles[i].length,buf+k,1);
memcpy(&outObj.profiles[i].type,buf+k+1,1);
outObj.profiles[i].data = malloc(outObj.profiles[i].length);
memcpy(outObj.profiles[i].data,buf+k+2,5);
k +=7;
}
for (int i=0;i<outObj.n;i++)
{
printf("\n------- Message %d --------",i+1);
printf("\nLength : %d",outObj.profiles[i].length);
printf("\nType : %d\n",outObj.profiles[i].type);
for (int j=0;j<5;j++)
{
printf(" Data[%d] : %d",j,outObj.profiles[i].data[j]);
}
}
for (int i=0;i<outObj.n;i++)
{
printf("\n\n---------- Values for Data Profile %d ------------",i+1);
int index1=0;
int sumReceivedData = 0;
int sumMyData = 0;
int sumMultpliedData = 0;
int my_data[10] = {0};
int myDataBinary[500] = {0};
int recData[500] = {0};
if (i==0)
{
my_data[0] = 1;
my_data[1] = 3;
my_data[2] = 9;
my_data[3] = 10;
}
else if (i==1)
{
my_data[0] = 1;
my_data[1] = 2;
my_data[2] = 3;
my_data[3] = 4;
my_data[4] = 5;
}
for (int i=0; i<sizeof(my_data)/sizeof(int);i++)
{
if (my_data[i] > 0)
{
index1 = my_data[i];
myDataBinary[index1] = 1;
//printf("my data %d = %d\n",index1,myDataBinary[index1]);
}
}
for (int j=0; j<outObj.profiles[i].length;j++)
{
if (outObj.profiles[i].data[j] > 0)
{
index1 = outObj.profiles[i].data[j];
recData[index1] = 1;
//printf("rec data %d = %d\n",index1,recData[index1]);
}
}
for (int i=0;i<500;i++)
{
sumReceivedData += recData[i];
sumMyData += myDataBinary[i];
sumMultpliedData += recData[i] * myDataBinary[i];
}
printf("\nrecSum = %d, \nmySum = %d, \nmultSum = %d\n",sumReceivedData,sumMyData,sumMultpliedData);
float rho = Pearson(sumMyData,sumReceivedData,sumMultpliedData);
printf("\nPearson Coefficient for Data Profile %d= %f\n",i+1,rho);
}
return 0;
}
//exit(EXIT_SUCCESS);
}
static float Pearson(int mySum, int recSum, int multSum)
{
float Cov =0;
float sdMyData = 0;
float sdReceivedData =0;
float rho;
int n = 500;
Cov = (1.0/(n-1))*(multSum - (1.0/n)*mySum*recSum);
sdMyData = sqrt((1.0/(n-1))*(mySum - (1.0/n)*mySum*mySum));
sdReceivedData = sqrt((1.0/(n-1))*(recSum - (1.0/n)*recSum*recSum));
printf("Covariance = %f\n",Cov);
printf("VarianceMyData = %f\n",sdMyData);
printf("VarianceRecData = %f\n",sdReceivedData);
if (sdMyData == 0.0 || sdReceivedData == 0.0)
rho = 0.0;
else
rho = Cov/(sdMyData*sdReceivedData);
return(rho);
}
It still needs a lot of work.

Error in socket programming and use of htonl(),htons() functions in C

I am pasting my client and server code below. My program is running fine, except that i am trying to send an ipaddress in my src and dest field, and for some reason, even though i am sending it as 131.199.166.232, it is printing as 232.166.199.131. But rest of my packet values are printed in a proper way. I have used memcpy(), so I feel its a memcpy thing, which somewhere I did wrong, but in Beej's guide as there is a section # the byte ordering in different computer architectures.....I have not used htonl() and all, so maybe it is because of that.Please guide me as where I am going wrong. Also kindly tell me the way i am sending data, how should the htonl() function can be used in my code....Thanks in advance.
Client:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define MAXPROFILES 2
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
unsigned char buf[1024];
unsigned int srcAddress = 2193598184;
unsigned int destAddress = 2193598182;
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
typedef struct profile_datagram_t
{
unsigned char src[4];
unsigned char dst[4];
unsigned char ver;
unsigned char n;
struct profile_t profiles[MAXPROFILES];
} header;
header outObj;
int j =0;
int i =0;
// for loop for doing the malloc so that we can allocate memory to all profiles
for(i=0;i<MAXPROFILES;i++){
outObj.profiles[i].data = malloc(5);
}
for(i=3;i>=0;i--){
outObj.src[i] = (srcAddress >> (i*8)) & 0xFF;
outObj.dst[i] = (destAddress >> (i*8)) & 0xFF;
printf("%d",outObj.src[i]);
}
outObj.ver = 1;
outObj.n = 2;
memcpy(buf,&outObj.src,4);
memcpy(buf+4,&outObj.dst,4);
memcpy(buf+8,&outObj.ver,1);
memcpy(buf+9,&outObj.n,1);
outObj.profiles[0].length = 5;
outObj.profiles[0].type = 1;
outObj.profiles[1].length = 5;
outObj.profiles[1].type = 2;
for(i=0;i<MAXPROFILES;i++){
for(j=0;j<5;j++){
outObj.profiles[i].data[j] = j+1;
}
}
int k = 10;
// for loop to do memcopy of length,type and data.
for(i=0;i<MAXPROFILES;i++){
memcpy(buf+k,&outObj.profiles[0].length,1);
memcpy(buf+k+1,&outObj.profiles[0].type,1);
memcpy(buf+k+2,outObj.profiles[0].data,5);
k +=7;
}
if (argc < 3) {
fprintf(stderr,"usage: %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]); //Convert ASCII to integer
sockfd = socket(AF_INET, SOCK_STREAM, 0); // socket file descriptor
if (sockfd < 0)
error("ERROR DETECTED !!! Problem in opening socket\n");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR DETECTED !!!, no such server found \n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr)); //clear the memory for server address
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
printf("Client 1 trying to connect with server host %s on port %d\n", argv[1], portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR in connection");
printf("SUCCESS !!! Connection established \n");
if (write(sockfd, buf, k) < 0)
{
error("Write error has occured ");
}
return 0;
}
Server Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAXPROFILES 2
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
struct sockaddr_in serv_addr, cli_addr;
unsigned char buf[1024];
int my_data2[10] = {1,3,9,10};
int my_data[10] = {1,2,3,4,5};
int myDataBinary[500] = {0};
int myDataBinary2[500] = {0};
int recData[500] = {0};
int index1=0;
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
typedef struct profile_datagram_t
{
unsigned char src[4];
unsigned char dst[4];
unsigned char ver;
unsigned char n;
struct profile_t profiles[MAXPROFILES];
} header;
header outObj;
int j =0;
int i =0;
if (argc < 2) {
fprintf(stderr,"usage: %s port_number1",argv[0]);
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR DETECTED !!! Problem in opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR DETECTED !!! There was a problem in binding");
listen(sockfd, 10);
clilen = sizeof(cli_addr);
printf("Server listening on port number %d...\n", serv_addr.sin_port);
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR DETECTED !!! the connection request was not accepted");
int rc = read(newsockfd,buf,100);
if(rc < 0){
printf("error");
}
else {
printf("success %d",rc);
}
memcpy(&outObj.src,buf+0,4);
memcpy(&outObj.dst,buf+4,4);
memcpy(&outObj.ver,buf+8,1);
memcpy(&outObj.n,buf+9,1);
printf("\nsrc ip = ");
for(int i=0;i<4;i++){
printf("%d ",outObj.src[i]);
}
printf("\ndest ip = ");
for(int i=0;i<4;i++){
printf("%d ",outObj.src[i]);
}
printf("\nversion = %d",outObj.ver);
printf("\nnumber = %d",outObj.n);
int k = 10;
for(i=0;i<outObj.n;i++){
memcpy(&outObj.profiles[i].length,buf+k,1);
memcpy(&outObj.profiles[i].type,buf+k+1,1);
outObj.profiles[i].data = malloc(outObj.profiles[i].length);
memcpy(outObj.profiles[i].data,buf+k+2,5);
k +=7;
}
for(int i=0;i<outObj.n;i++){
printf("\nMessage %d :",i+1);
printf("\nLength : %d",outObj.profiles[i].length);
printf("\nType : %d",outObj.profiles[i].type);
for(int j=0;j<5;j++){
printf("\ndata %d : %d",j,outObj.profiles[i].data[j]);
}
}
for(int i=0; i<sizeof(my_data)/sizeof(int);i++)
{
if(my_data[i] > 0){
index1 = my_data[i];
myDataBinary[index1] = 1;
printf("my data %d = %d\n",index1,myDataBinary[index1]);
}
}
for(int i=0; i<sizeof(my_data2)/sizeof(int);i++)
{
if(my_data2[i] > 0){
index1 = my_data2[i];
myDataBinary2[index1] = 1;
printf("my data %d = %d\n",index1,myDataBinary2[index1]);
}
}
int sumRecievedData = 0;
int sumMyData = 0;
int sumMultpliedData = 0;
float Cov =0;
float sdMyData = 0;
float sdRecievedData =0;
int n = 500;
float rho;
for(int i=0;i<outObj.n;i++){
index1=0;
for (int j=0; j<outObj.profiles[i].length;j++) {
if(outObj.profiles[i].data[j] > 0){
index1 = outObj.profiles[i].data[j];
recData[index1] = 1;
printf("rec data %d = %d\n",index1,recData[index1]);
}
}
}
for(int i=0;i<500;i++){
sumRecievedData += recData[i];
sumMyData += myDataBinary[i];
sumMultpliedData += recData[i] * myDataBinary[i];
}
printf("recSum = %d, mySum = %d, multSum = %d",sumRecievedData,sumMyData,sumMultpliedData);
Cov = (1.0/(n-1))*(sumMultpliedData - (1.0/n)*sumMyData*sumRecievedData);
sdMyData = sqrt((1.0/(n-1))*(sumMyData - (1.0/n)*sumMyData*sumMyData));
sdRecievedData = sqrt((1.0/(n-1))*(sumRecievedData - (1.0/n)*sumRecievedData*sumRecievedData));
printf("Covariance = %f, Variance 1 = %f, Variance 2 = %f",Cov,sdMyData,sdRecievedData);
if (sdMyData == 0.0 || sdRecievedData == 0.0){
rho = 0.0;
}else{
rho = Cov/(sdMyData*sdRecievedData);
}
printf("Pearson Coefficient = %f",rho);
return 0;
}
You need to decide how you want to send the data and convert data in that format right before:
if (write(sockfd, buf, k) < 0)
You use either of following:
htons() host to network short
htonl() host to network long
ntohs() network to host short
ntohl() network to host long
In general, you should use regular integers instead of byte arrays in your structs, then use hton...() to put those values be in network byte order when placing them into send buffers, and then use ntoh...() to put the values back into host byte order when copying them out of receive buffers. Your code operates in host byte order. Network transmissions should use network byte order.
With that said, IPv4 addresses are a special case, because there are extra functions available() for working with IP strings, which expect the numeric values to be in network byte order only.
Try something like this:
Client:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define MAXPROFILES 2
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
struct profile_datagram_t
{
unsigned long src;
unsigned long dst;
unsigned char ver;
unsigned char n;
profile_t profiles[MAXPROFILES];
};
int main(int argc, char *argv[])
{
if (argc < 3)
{
fprintf(stderr,"usage: %s hostname port\n", argv[0]);
exit(0);
}
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
unsigned char buf[1024];
profile_datagram_t outObj;
int i;
int j;
outObj.src = inet_addr("130.191.166.232");
outObj.dst = inet_addr("130.191.166.230");
outObj.ver = 1;
outObj.n = 2;
memcpy(&buf[0], &outObj.src, 4);
memcpy(&buf[4], &outObj.dst, 4);
memcpy(&buf[8], &outObj.ver, 1);
memcpy(&buf[9], &outObj.n, 1);
int k = 10;
for(i = 0; i < MAXPROFILES; ++i)
{
outObj.profiles[i].length = 5;
outObj.profiles[i].type = i+1;
outObj.profiles[i].data = malloc(5);
for(j = 0; j < 5; ++j)
{
outObj.profiles[i].data[j] = j+1;
}
memcpy(&buf[k], &outObj.profiles[i].length, 1);
memcpy(&buf[k+1], &outObj.profiles[i].type, 1);
memcpy(&buf[k+2], outObj.profiles[i].data, 5);
k +=7;
}
sockfd = socket(AF_INET, SOCK_STREAM, 0); // socket file descriptor
if (sockfd < 0)
error("ERROR in opening socket\n");
server = gethostbyname(argv[1]);
if (server == NULL)
{
closesocket(sockfd);
fprintf(stderr,"ERROR DETECTED !!!, no such server found \n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr)); //clear the memory for server address
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
portno = atoi(argv[2]); //Convert ASCII to integer
serv_addr.sin_port = htons(portno);
printf("Client 1 trying to connect with server host %s on port %d\n", argv[1], portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
{
closesocket(sockfd);
error("ERROR in connect");
}
printf("SUCCESS !!! Connection established \n");
i = 0;
while (i < k)
{
int rc = write(sockfd, &buf[i], k-i);
if (rc < 0)
{
closesocket(sockfd);
error("ERROR in write");
}
i += rc;
}
closesocket(sockfd);
return 0;
}
Server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAXPROFILES 2
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
struct profile_datagram_t
{
unsigned long src;
unsigned long dst;
unsigned char ver;
unsigned char n;
profile_t profiles[MAXPROFILES];
};
int main(int argc, char *argv[])
{
if (argc < 2)
{
fprintf(stderr, "usage: %s port_number1", argv[0]);
exit(1);
}
int sockfd, newsockfd, portno, clilen;
struct sockaddr_in serv_addr, cli_addr;
struct in_addr addr;
unsigned char buf[1024];
int buflen;
profile_datagram_t outObj;
int i;
int j;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR in opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR in binding");
if (listen(sockfd, 10)) < 0)
error("ERROR in listening");
printf("Server listening on port number %d...\n", portno);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
closesocket(sockfd);
if (newsockfd < 0)
error("a connection request was not accepted");
buflen = 0;
while (buflen < 10)
{
int rc = read(newsockfd, &buf[buflen], 10-buflen);
if(rc <= 0)
{
closesocket(newsockfd);
error("ERROR in read");
}
buflen += rc;
}
memcpy(&outObj.src, &buf[0], 4);
memcpy(&outObj.dst, &buf[4], 4);
memcpy(&outObj.ver, &buf[8], 1);
memcpy(&outObj.n, &buf[9], 1);
addr.s_addr = outObj.src;
printf("\nsrc ip = %s", inet_ntoa(&addr));
addr.s_addr = outObj.dst;
printf("\ndest ip = %s", inet_ntoa(&addr));
printf("\nversion = %d", outObj.ver);
printf("\nnumber = %d", outObj.n);
for(i = 0; i < outObj.n; ++i)
{
buflen = 0;
while (buflen < 2)
{
int rc = read(newsockfd, &buf[buflen], 2-buflen);
if (rc <= 0)
{
closesocket(newsockfd);
error("ERROR in read");
}
buflen += rc;
}
memcpy(&outObj.profiles[i].length, &buf[0], 1);
memcpy(&outObj.profiles[i].type, &buf[1], 1);
outObj.profiles[i].data = malloc(outObj.profiles[i].length);
buflen = 0;
while (buflen < outObj.profiles[i].length)
{
int rc = read(newsockfd, &buf[buflen], outObj.profiles[i].length-buflen);
if (rc <= 0)
{
closesocket(newsockfd);
error("ERROR in read");
}
buflen += rc;
}
printf("\nMessage %d :",i+1);
printf("\nLength : %d", outObj.profiles[i].length);
printf("\nType : %d", outObj.profiles[i].type);
for(j = 0; j < outObj.profiles[i].length; j)
printf("\ndata[%d] : %d", j, outObj.profiles[i].data[j]);
}
closesocket(newsockfd);
return 0;
}

Resources