ChaoticMind
August 13th, 2008, 12:15 PM
Hello,
I wrote a program that exchanges UDP packets, but for some reason the Identification part of the IP header is always zero. The same code on windows (using winsock) would properly generate a random identification in the IP header.
I believe that having an id for the IP packet is important in case fragmentation etc occurs.
Note that the actual value for the identification part of the IP header was either tcpdump or wireshark.
I will attach the stripped down (preliminary) version of both the client and the server.
Here is the client code:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) { // we will use the arguments in the next revision to specify amount of packets and how big they should be, destination IP and other similar parameters.
int socketDescriptor; // this will hold the socket info, ie it will represent our socket.
struct sockaddr_in serverAddress; // this will hold the server information, its IP, the port it should send to, address type, etc
unsigned short int serverPort = 51234; // we're setting the port manually here. it's a variable because we want to change it later on through the parameters. we'll put here the default value. Note that we can use any of the unregistered ports (Ports 49,152 through 65,535)
if ((socketDescriptor = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { // this line does two functions, it creates a socket of type AF_INET which is an internet address (as opposed to AF_UNIX which is a file pathname). Also, SOCK_DGRAM represents a UDP (connectionless) socket, as opposed to SOCK_STREAM which would be a TCP socket. The third argument is for special options which we don't need. This line also checks if socket returns -1 which would indicate that there was an error creating the socket.
printf("Could not create socket. \n");
exit(1); // quits the program
}
serverAddress.sin_family = AF_INET; // sets the server address to type AF_INET, similar to the socket we will use.
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); // this sets the server address.
serverAddress.sin_port = serverPort; // sets the server port.
char msg[] = "Hello World. "; // For now, this is the message we will send.
printf("We will send the message: \"%s\" to the server. \n", msg);
if (sendto(socketDescriptor, msg, strlen(msg), 0, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { // We're sending over the socket described by socketDescriptor, and to the address described by serverAddress, the message held by 'msg'. sendto() returns -1 if it wasn't successful. Note that it doesn't return -1 if the connection couldn't be established (UDP)
printf("Could not send data to the server. \n");
exit(1);
}
return 0;
}
Here is the Server code:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
int main() {
int socketDescriptor;
unsigned short int serverPort = 51234;
unsigned int msgSize = 100; // the max receivable size is msgSize. We should have this number larger than the max amount of data that we can receive. For now, this doesn't matter.
struct sockaddr_in serverAddress, clientAddress; // we are going to store information for both the client and the server.
socklen_t clientAddressLength;
char msg[msgSize]; // msg received will be stored here.
socketDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
// we fill the server information here.
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddress.sin_port = serverPort;
if (bind(socketDescriptor, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { // we now have to bind the socket to the server descriptions stored in serverAddress. This will tell the socket on which port to listen on etc.. Again, bind returns -1 upon failure.
printf("Could not bind socket");
exit(1);
}
// now we wait for connections...
listen(socketDescriptor, 2); // sets the queue size to two messages at a time. The number '2' was chosen arbitrarely. This line is optional.
printf("Waiting for data on UDP port %i\n", serverPort);
while(1) { // endless loop to keep on receiving data.
clientAddressLength = sizeof(clientAddress);
memset(msg, 0, msgSize); // intialize msg to zero.
// now we receive the data, and check for errors.
if (recvfrom(socketDescriptor, msg, msgSize, 0, (struct sockaddr *)&clientAddress, &clientAddressLength) < 0) { // we now will wait to receive data on the socket described by socketDescriptor from a client. We also store this client information in clientAddress. This is useful if we want to reply to the client, or otherwise have information relating to where the received data initiated from. Again, the function recvfrom() returns -1 on error.
printf("An error occured while receiving data... Program is terminating. ");
exit(1);
}
// we stored the information about the client in the strucct clientAddress.
printf("Received from %s on UDP port %d (port at sender is %d): \n%s\n", inet_ntoa(clientAddress.sin_addr), serverAddress.sin_port, ntohs(clientAddress.sin_port), msg); // note how we read the serverside port from serverAddress, and the client-side port from clientAddress, since it now holds information about the client, including which port it sent from.
} // end while
return 0;
}
Is there something missing that I should do? Do i have to manually set the id?
This is my first attempt at network programming, so I might be missing something basic..
I wrote a program that exchanges UDP packets, but for some reason the Identification part of the IP header is always zero. The same code on windows (using winsock) would properly generate a random identification in the IP header.
I believe that having an id for the IP packet is important in case fragmentation etc occurs.
Note that the actual value for the identification part of the IP header was either tcpdump or wireshark.
I will attach the stripped down (preliminary) version of both the client and the server.
Here is the client code:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) { // we will use the arguments in the next revision to specify amount of packets and how big they should be, destination IP and other similar parameters.
int socketDescriptor; // this will hold the socket info, ie it will represent our socket.
struct sockaddr_in serverAddress; // this will hold the server information, its IP, the port it should send to, address type, etc
unsigned short int serverPort = 51234; // we're setting the port manually here. it's a variable because we want to change it later on through the parameters. we'll put here the default value. Note that we can use any of the unregistered ports (Ports 49,152 through 65,535)
if ((socketDescriptor = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { // this line does two functions, it creates a socket of type AF_INET which is an internet address (as opposed to AF_UNIX which is a file pathname). Also, SOCK_DGRAM represents a UDP (connectionless) socket, as opposed to SOCK_STREAM which would be a TCP socket. The third argument is for special options which we don't need. This line also checks if socket returns -1 which would indicate that there was an error creating the socket.
printf("Could not create socket. \n");
exit(1); // quits the program
}
serverAddress.sin_family = AF_INET; // sets the server address to type AF_INET, similar to the socket we will use.
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); // this sets the server address.
serverAddress.sin_port = serverPort; // sets the server port.
char msg[] = "Hello World. "; // For now, this is the message we will send.
printf("We will send the message: \"%s\" to the server. \n", msg);
if (sendto(socketDescriptor, msg, strlen(msg), 0, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { // We're sending over the socket described by socketDescriptor, and to the address described by serverAddress, the message held by 'msg'. sendto() returns -1 if it wasn't successful. Note that it doesn't return -1 if the connection couldn't be established (UDP)
printf("Could not send data to the server. \n");
exit(1);
}
return 0;
}
Here is the Server code:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
int main() {
int socketDescriptor;
unsigned short int serverPort = 51234;
unsigned int msgSize = 100; // the max receivable size is msgSize. We should have this number larger than the max amount of data that we can receive. For now, this doesn't matter.
struct sockaddr_in serverAddress, clientAddress; // we are going to store information for both the client and the server.
socklen_t clientAddressLength;
char msg[msgSize]; // msg received will be stored here.
socketDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
// we fill the server information here.
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddress.sin_port = serverPort;
if (bind(socketDescriptor, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { // we now have to bind the socket to the server descriptions stored in serverAddress. This will tell the socket on which port to listen on etc.. Again, bind returns -1 upon failure.
printf("Could not bind socket");
exit(1);
}
// now we wait for connections...
listen(socketDescriptor, 2); // sets the queue size to two messages at a time. The number '2' was chosen arbitrarely. This line is optional.
printf("Waiting for data on UDP port %i\n", serverPort);
while(1) { // endless loop to keep on receiving data.
clientAddressLength = sizeof(clientAddress);
memset(msg, 0, msgSize); // intialize msg to zero.
// now we receive the data, and check for errors.
if (recvfrom(socketDescriptor, msg, msgSize, 0, (struct sockaddr *)&clientAddress, &clientAddressLength) < 0) { // we now will wait to receive data on the socket described by socketDescriptor from a client. We also store this client information in clientAddress. This is useful if we want to reply to the client, or otherwise have information relating to where the received data initiated from. Again, the function recvfrom() returns -1 on error.
printf("An error occured while receiving data... Program is terminating. ");
exit(1);
}
// we stored the information about the client in the strucct clientAddress.
printf("Received from %s on UDP port %d (port at sender is %d): \n%s\n", inet_ntoa(clientAddress.sin_addr), serverAddress.sin_port, ntohs(clientAddress.sin_port), msg); // note how we read the serverside port from serverAddress, and the client-side port from clientAddress, since it now holds information about the client, including which port it sent from.
} // end while
return 0;
}
Is there something missing that I should do? Do i have to manually set the id?
This is my first attempt at network programming, so I might be missing something basic..