Module 3 Programs
Pulse server program
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <process.h>
#include "msg_def.h" //layout of msgs should always defined by a struct, here's its definition
int
calculate_checksum(char *text);
typedef union
uint16_t type;
cksum_msg_t cksum_msg;
struct _pulse pulse;
} recv_buf_t;
int main(void)
int chid;
int pid;
rcvid_t rcvid;
// cksum_msg_t msg;
recv_buf_t rbuf;
int status;
int checksum;
//PUT CODE HERE to create a channel, store channel id in the chid variable
chid = ChannelCreate(0);
if (chid == -1)
{ //was there an error creating the channel?
perror("ChannelCreate()"); //look up the errno code and print
exit(EXIT_FAILURE);
pid = getpid(); //get our own pid
printf("Server's pid: %d, chid: %d\n", pid, chid); //print our pid/chid so
//client can be told where to connect
while (1)
//PUT CODE HERE to receive msg from client, store the receive id in rcvid
rcvid = MsgReceive(chid, &rbuf, sizeof(rbuf), NULL );
if (rcvid == -1)
{ //was there an error receiving msg?
perror("MsgReceive"); //look up errno code and print
exit(EXIT_FAILURE); //give up
else if (rcvid == 0)
printf("we got a pulse with a code of %d, and value of %#lx\n",
[Link],
[Link].sival_long);
else // we got a message
if ([Link] == CKSUM_MSG_TYPE)
printf("Got a checksum message\n");
checksum =
calculate_checksum(rbuf.cksum_msg.string_to_cksum);
//PUT CODE HERE TO reply to client with checksum, store the
return status in status
status = MsgReply(rcvid, EOK, &checksum, sizeof(checksum));
if (status == -1)
perror("MsgReply");
else
// unknown message type, unblock client with an error
if (MsgError(rcvid, ENOSYS) == -1)
perror("MsgError");
return 0;
int calculate_checksum(char *text)
char *c;
int cksum = 0;
for (c = text; *c != '\0'; c++)
cksum += *c;
return cksum;
}
Pulse client program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/neutrino.h>
#include "msg_def.h"
int main(int argc, char* argv[])
int coid; //Connection ID to server
cksum_msg_t msg;
int incoming_checksum; //space for server's reply
int status; //status return value used for MsgSend
int server_pid; //server's process ID
int server_chid; //server's channel ID
if (argc != 4)
printf("ERROR: This program must be started with commandline arguments, for
example:\n\n");
printf(" client 482834 1 abcdefghi \n\n");
printf(" 1st arg(482834): server's pid\n");
printf(" 2nd arg(1): server's chid\n");
printf(" 3rd arg(abcdefghi): string to send to server\n"); //to make it
//easy, let's not bother handling spaces
exit(EXIT_FAILURE);
server_pid = atoi(argv[1]);
server_chid = atoi(argv[2]);
printf("attempting to establish connection with server pid: %d, chid %d\n", server_pid,
server_chid);
//PUT CODE HERE to establish a connection to the server's channel, store the
//connection id in the variable 'coid'
coid = ConnectAttach(0, server_pid, server_chid, _NTO_SIDE_CHANNEL, 0);
if (coid == -1)
{ //was there an error attaching to server?
perror("ConnectAttach"); //look up error code and print
exit(EXIT_FAILURE);
msg.msg_type = CKSUM_MSG_TYPE;
strlcpy(msg.string_to_cksum, argv[3], sizeof(msg.string_to_cksum));
printf("Sending string: %s\n", msg.string_to_cksum);
status = MsgSendPulse(coid, -1, 3, 0xdeadc0de);
if (status == -1)
perror("MsgSendPulse");
//PUT CODE HERE to send message to server and get the reply
status = MsgSend(coid, &msg, sizeof(msg.msg_type) + strlen(msg.string_to_cksum) + 1,
&incoming_checksum, sizeof(incoming_checksum));
if (status == -1)
{ //was there an error sending to server?
perror("MsgSend");
exit(EXIT_FAILURE);
}
printf("received checksum=%d from server\n", incoming_checksum);
printf("MsgSend return status: %d\n", status);
return EXIT_SUCCESS;
}
Name lookup - Server
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <process.h>
#include "msg_def.h" //layout of msgs should always defined by a struct, here's its definition
#include <sys/dispatch.h>
int
calculate_checksum(char *text);
typedef union
uint16_t type;
cksum_msg_t cksum_msg;
struct _pulse pulse;
} recv_buf_t;
int main(void)
// int chid;
int pid;
rcvid_t rcvid;
// cksum_msg_t msg;
recv_buf_t rbuf;
int status;
int checksum;
name_attach_t *att;
// register our name
att = name_attach(NULL, SERVER_NAME, 0);
if (att == NULL)
perror("name_attach");
exit(EXIT_FAILURE);
// chid = ChannelCreate( 0 );
// //PUT CODE HERE to create a channel, store channel id in the chid variable
// if(chid == -1) { //was there an error creating the channel?
// perror("ChannelCreate()"); //look up the errno code and print
// exit(EXIT_FAILURE);
// }
//
pid = getpid(); //get our own pid
printf("Server's pid: %d, chid: %d\n", pid, att->chid); //print our pid/chid so
//client can be told where to
//connect
while (1)
rcvid = MsgReceive(att->chid, &rbuf, sizeof(rbuf), NULL );
//PUT CODE HERE to receive msg from client, store the receive id in rcvid
if (rcvid == -1)
{ //was there an error receiving msg?
perror("MsgReceive"); //look up errno code and print
exit(EXIT_FAILURE); //give up
else if (rcvid == 0)
{
printf("we got a pulse with a code of %d, and value of %#lx\n",
[Link], [Link].sival_long);
switch([Link])
case _PULSE_CODE_DISCONNECT:
// a client went away, if we had any data clean up,
then always release scoid
ConnectDetach([Link]);
break;
case CKSUM_PULSE_CODE:
// This was our expected pulse code
printf("This is our expected CKSUM_PULSE_CODE\n");
break;
default:
// An unexpected pulse code, but we can't report an error
as pulses are non-blocking
printf("This was an unexpected pulse code\n");
break;
else // we got a message
printf("we got a message with type %d\n", [Link]);
switch ([Link])
case CKSUM_MSG_TYPE:
printf("Got a checksum message\n");
checksum =
calculate_checksum(rbuf.cksum_msg.string_to_cksum);
//PUT CODE HERE TO reply to client with checksum,
store the return status in statussum));
status = MsgReply(rcvid, EOK, &checksum, sizeof(checksum));
if (status == -1)
perror("MsgReply");
break;
default:
// unknown message type, unblock client with an error
if (MsgError(rcvid, ENOSYS) == -1)
perror("MsgError");
return 0;
int calculate_checksum(char *text)
char *c;
int cksum = 0;
for (c = text; *c != '\0'; c++)
cksum += *c;
return cksum;
}
Name lookup - Client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/neutrino.h>
#include "msg_def.h"
#include <sys/dispatch.h>
int main(int argc, char* argv[])
int coid; //Connection ID to server
cksum_msg_t msg;
int incoming_checksum; //space for server's reply
int status; //status return value used for MsgSend
// int server_pid; //server's process ID
// int server_chid; //server's channel ID
// if(4 != argc) {
// printf("ERROR: This program must be started with commandline
arguments, for example:\n\n");
// printf(" client 482834 1 abcdefghi \n\n");
// printf(" 1st arg(482834): server's pid\n");
// printf(" 2nd arg(1): server's chid\n");
// printf(" 3rd arg(abcdefghi): string to send to server\n"); //to make it
// //easy, let's not bother handling spaces
// exit(EXIT_FAILURE);
// }
if (argc != 2)
{
printf("ERROR: provide a string to send\n");
exit(EXIT_FAILURE);
// server_pid = atoi(argv[1]);
// server_chid = atoi(argv[2]);
//
//
// printf("attempting to establish connection with server pid: %d, chid %d\n",
server_pid, server_chid);
//
// coid = ConnectAttach( 0, server_pid, server_chid, _NTO_SIDE_CHANNEL, 0 );
//PUT CODE HERE to establish a connection to the server's channel, store the
//connection id in the variable 'coid'
// look up name, rather than get it from command line
coid = name_open(SERVER_NAME, 0);
if (coid == -1)
{ //was there an error attaching to server?
// perror("ConnectAttach"); //look up error code and print
perror("name_open");
exit(EXIT_FAILURE);
msg.msg_type = CKSUM_MSG_TYPE;
strlcpy(msg.string_to_cksum, argv[1], sizeof(msg.string_to_cksum));
printf("Sending string: %s\n", msg.string_to_cksum);
if (MsgSendPulse(coid, -1, CKSUM_PULSE_CODE, 0xc0dedeed) == -1) {
perror("MsgSendPulse");
}
//PUT CODE HERE to send message to server and get the reply
status = MsgSend(coid, &msg, sizeof(msg.msg_type) + strlen(msg.string_to_cksum) + 1,
&incoming_checksum, sizeof(incoming_checksum));
if (status == -1)
{ //was there an error sending to server?
perror("MsgSend");
exit(EXIT_FAILURE);
printf("received checksum=%d from server\n", incoming_checksum);
printf("MsgSend return status: %d\n", status);
return EXIT_SUCCESS;
}
IOV server
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/dispatch.h>
#include <sys/neutrino.h>
#include "iov_server.h"
typedef union
uint16_t msg_type;
struct _pulse pulse;
cksum_header_t cksum_hdr;
} msg_buf_t;
int calculate_checksum(char *text);
int main(void)
rcvid_t rcvid;
name_attach_t* attach;
msg_buf_t msg;
int status;
int checksum;
char* data;
struct _msg_info minfo;
attach = name_attach(NULL, CKSUM_SERVER_NAME, 0);
if (attach == NULL)
{ //was there an error creating the channel?
perror("name_attach"); //look up the errno code and print
exit(EXIT_FAILURE);
while (1)
printf("Waiting for a message...\n");
rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), &minfo);
if (rcvid == -1)
{ //was there an error receiving msg?
perror("MsgReceive"); //look up errno code and print
exit(EXIT_FAILURE); //give up
else if (rcvid > 0)
{ //msg
// did we get enough bytes for a type?
if ([Link] < sizeof(msg.msg_type))
MsgError(rcvid, EBADMSG);
continue;
switch (msg.msg_type)
case CKSUM_IOV_MSG_TYPE:
// did we get a full header?
if ([Link] < sizeof(msg.cksum_hdr))
MsgError(rcvid, EBADMSG);
continue;
}
printf("Received a checksum request msg, header says the data is %d bytes\n",
msg.cksum_hdr.data_size);
// Did the client send all the data (now check srcmsglen)?
if([Link] < sizeof(msg.cksum_hdr) + msg.cksum_hdr.data_size)
MsgError(rcvid, EBADMSG);
continue;
data = malloc(msg.cksum_hdr.data_size);
if (data == NULL)
if (MsgError(rcvid, ENOMEM ) == -1)
perror("MsgError");
continue;
else
status = MsgRead(rcvid, data,
msg.cksum_hdr.data_size,sizeof(cksum_header_t));
if (status == -1)
const int save_errno = errno;
perror("MsgRead");
MsgError(rcvid, save_errno);
free(data);
continue;
checksum = calculate_checksum(data);
free(data);
status = MsgReply(rcvid, EOK, &checksum, sizeof(checksum));
if (status == -1)
if (errno == ESRVRFAULT) {
perror("MsgReply fatal");
exit(EXIT_FAILURE);
perror("MsgReply");
break;
default:
if (MsgError(rcvid, ENOSYS) == -1)
perror("MsgError");
break;
else
{ //pulse
switch ([Link])
case _PULSE_CODE_DISCONNECT:
printf("Received disconnect pulse\n");
if (ConnectDetach([Link]) == -1)
perror("ConnectDetach");
break;
case _PULSE_CODE_UNBLOCK:
printf("Received unblock pulse\n");
if (MsgError([Link].sival_long, -1) == -1)
perror("MsgError");
break;
default:
printf("unknown pulse received, code = %d\n", [Link]);
break;
return 0;
int calculate_checksum(char *text)
char *c;
int cksum = 0;
for (c = text; *c != '\0'; c++)
cksum += *c;
return cksum;
}
IOV Client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/neutrino.h>
#include "iov_server.h"
#include <sys/dispatch.h>
int main(int argc, char* argv[])
int coid; //Connection ID to server
cksum_header_t hdr; //msg header will specify how many bytes of data will follow
int incoming_checksum; //space for server's reply
int status; //status return value
iov_t siov[2]; //create a 2 part iov
if (argc != 2)
printf("ERROR: This program must be started with a command-line arg, for
example:\n\n");
printf(" iov_client abcdefjhi \n\n");
printf(" where 1st arg(abcdefghi) is the text to be sent to the server to be
checksum'd\n");
exit(EXIT_FAILURE);
// locate the server
coid = name_open(CKSUM_SERVER_NAME, 0);
if (coid == -1)
{ //was there an error attaching to server?
perror("name_open"); //look up error code and print
exit(EXIT_FAILURE);
printf("Sending the following text to checksum server: %s\n", argv[1]);
// build the header
hdr.msg_type = CKSUM_IOV_MSG_TYPE;
hdr.data_size = strlen(argv[1]) + 1;
// setup the message as a two part iov, first the header then the data
SETIOV (&siov[0], &hdr, sizeof hdr);
SETIOV (&siov[1], argv[1], hdr.data_size);
// and send the message off to the server
status = MsgSendvs(coid, siov, 2, &incoming_checksum, sizeof incoming_checksum);
if (status == -1)
{ //was there an error sending to server?
perror("MsgSend");
exit(EXIT_FAILURE);
printf("received checksum=%d from server\n", incoming_checksum);
printf("MsgSend return status: %d\n", status);
return EXIT_SUCCESS;