I can send/receive data over sockets using a char array but can’t figure out a way to send structures . I found a lot of articles but they are to hard to understand .. As far as I know we have to use a function called snprintf to make packets of data and then some other to revive it . Please I am looking for a very reliable but simple way of data transfer .. Here is some code I wrote to send via char array
int main()
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
printf("\n\n...Server is starting up...\n\n");
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(4567);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
printf("Bind successful\n");
listen(listenfd, 10);
printf("Ready: Waiting for clients\n");
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
Client
int main(int argc, char *argv[])
{
int sockfd = 0 /*Socket Descriptor*/, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2) {
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(4567);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0) {
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0) {
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF) {
printf("\n Error : Fputs error\n");
}
}
if(n < 0) {
printf("\n Read error \n");
}
return 0;
}
For sending structures, in summary: don’t. As in, don’t attempt to take a structure pointer, the sizeof operator, and a socket send() and expect things will all work out fine, because even if it looks like it works, its already broken in design.
Rather, your structure members should be laid out in a well-defined byte-format that is understood and managed on both ends of the socket connection by common code that is portable. This format (e.g. the protocol) should have portable routines for both assembling your structure into a byte array, and disassembling it out of one. Using these routines on both the client and server side, accounting for sizes, endianness of numeric values, etc, is ultimately the only way to to this both (a) right, and (b) portable.
There are generic solutions available (such as boost::serialization), but ultimately there is no silver bullet. So consider all options and go with the most portable, simplest approach you can.