Each running Nachos is a node in the network, this node is emulated as a UNIX process; a network provides the communication between those nodes, these networks are emulated by UNIX sockets.
We can try this by running '
nachos -m 0 -o 1' and '
nachos -m 1 -o 0'simultaneously, in two different terminals. For this, you need implamantation of locks and condition variables.
For now, I'm just explaining nachos' network code.
nettest.cc
MailTest : Function for test out message delivery.
farAddr : machine's ID, to wich we are sending the message.
outPktHdr, OutMailHdr : Outcoming message properties.
inPktHdr, inMailHdr : Incoming message properties.
const char *data = "Hello there" : Message that we are sendig to the other machin, at mailbox #0.
const char *ack = "Got it" : This is gonna be the acknowledgment of receiving the message.
MaxMailSize: Maximum real data that a message can include. (defined in post.cc)
outPktHdr.to = radAddr / outMailHdr.to = 0: Destination machin. Its mailbox it's mailbox #0
outMailHdr.from: Machine that is sending the message. Reply to mailbox #1
outMailHdr.length = strlen(data) + 1: measuring message size ("Hello there!")
postOffice->Send: Sending first message.
postOffice->Receive : Waiting message from the other machine.
0, &inPktHdr, &inMailHdr, buffer: incoming mesagge properties.
fflush(stdout): cleaning output buffer.
Machine is going to know were te incoming message is coming from (inPktHdr.from, inMailHdr.from)
Then it is sending the acknowledgment to the other machine (outPktHdr.to , outMail.Hdr.to)
The size of the outgoing message is measured by outMailHdr.lenght = strleng(ack) +1
Sending the ack: postOffice->Send
Waiting the ack of the second machin from the first sended message.
Done!
----------------------------------------------------------------------
post.cc
This is where we are going to storage our messages.
to: destination mailbox.
from: Where we are going to reply the message.
length: size of the message. Size cannot be negative.
Maximum data that a message can include.
The format of a message we send/recieve is by layers:
- Network Header (PacketHeader)
- Post Office Header (MailHeader)
- data
This class define this format.
Mail ( PacketHeader pktH , MailHeader mailH , const char *msgData ) : concatenate headers to data.
char data[MaxMailSize]: message data. Array of MAXMAILSIZE size.
This class defines the place where we are going to storage the messages.
Mailbox() : Allocate and initialize mail box
~Mailbox() : De-allocate mail box.
SynchList<Mail*> *messages : A mailbox is a list of messages.
Post Office is a collection of mailboxes. This class defines a Post Office.
PostOffice : allocate and initalizate.
De-allocate.
Send a message to the other machine mailbox.
Retrieve the ack.
Wait incoming message. Put them in the correct mailbox.
Interrupt Handler: Next packet can now be sent.
Interrupt Handler: incoming message has arrived.
---------------------------------------------------------------------
These are the files that nettest.cc includes.
Sockets implementation: Client#include
#include
#include
#define SERVER_PORT 9999
these are the libraries which define socket and the internet socket also a server port.
if( ( hp = gethostbyname( argv[1] ) ) == NULL )
{
printf( "%s: %s unknown host\n", argv[0], argv[1] );
exit( 1 );
}
bcopy( hp->h_addr_list[0], (char*)&server_addr.sin_addr, hp->h_length );
this part of code gets the host and if it doesn't get it print a error message
if( ( sd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
{
perror( "client: socket failed" );
exit( 1 );
}
if( connect( sd, (struct sockaddr*)&server_addr,
sizeof(server_addr) ) == -1 )
{
perror( "client: connect FAILED:" );
exit( 1 );
}
printf("connect() successful! will send a message to server\n");
printf("Input a string:\n" );
while( scanf( "%s", buf) != EOF)
{
write(sd, buf, sizeof(buf));
read(sd, buf, sizeof(buf));
printf("SERVER ECHOED: %s\n", buf);
}
hier the socket is created and conected with the client and server
Sockets implementation: Serverif( listen( sd, 1 ) == -1 )
{
perror( "server: listen failed" );
exit( 1 );
}
printf("SERVER is listening for clients to establish a connection\n");
if( ( ns = accept( sd, (struct sockaddr*)&client_addr,
&client_len ) ) == -1 )
{
perror( "server: accept failed" );
exit( 1 );
}
printf("accept() successful.. a client has connected! waiting for a message\n");
the server is listenig for clients and if is conected successfuly then you can write the message....
OUTPUT
Sources:
http://www.dreamincode.net/forums/topic/62891-what-is-fflush/
http://athena.nitc.ac.in/labs/os/html/nettest_8cc.html