代写代考 CMPUT 379, U. of Alberta)

3/18/22, 8:02 PM webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc
# ————————————————————
# sockMsg – A client-server program to test formatted messages and TCP sockets
# compile with: g++ sockMsg.cc -o sockMsg

Copyright By PowCoder代写 加微信 powcoder

# Usage: sockMsg -s
# sockMsg -c serverName
# Summary:
# – The server listens to port MYPORT, and accepts up to NCLIENT
# connections using poll(). For each client, the server accepts
# a sequence of messages and replies to each message with an ACK.
# – Each client connects to the server, and iterates NITER times.
# In each iteration, a sequence of messages are transmitted.
# Author: Prof. (for CMPUT 379, U. of Alberta)
# ————————————————————
#define _REENTRANT
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include #include
#include
using namespace std;
// ——————————
#define MAXLINE 132
#define MAXWORD 32
#define NCLIENT 5 // client limit
#define MYPORT 2222
#define NF 3
#define NITER 10
#define MSG_KINDS 5
// ——————————
// number of fields in each message
// number of iterations per client
typedef enum { STR, INT, FLOAT, DONE, ACK } KIND; // Message kinds
char KINDNAME[][MAXWORD]= { “STR”, “INT”, “FLOAT”, “DONE”, “ACK” };
typedef struct { char d[NF][MAXLINE]; } MSG_STR;
typedef struct { int d[NF]; } MSG_INT;
typedef struct {float d[NF]; } MSG_FLOAT;
webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc

3/18/22, 8:02 PM _ webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc
typedef union { MSG_STR mStr; MSG_INT mInt; MSG_FLOAT mFloat; } MSG;
typedef struct { KIND kind; MSG msg; } FRAME;
#define MAXBUF sizeof(FRAME)
typedef struct sockaddr SA;
// ——————————
// The WARNING and FATAL functions are due to the authors of
// the AWK Programming Language.
void FATAL (const char *fmt, … )
va_list ap;
fflush (stdout);
va_start (ap, fmt); vfprintf (stderr, fmt, ap); va_end(ap);
fflush (NULL);
void WARNING (const char *fmt, … )
va_list ap;
fflush (stdout);
va_start (ap, fmt); vfprintf (stderr, fmt, ap); va_end(ap);
// ————————————————————
// ——————————
// composeMSTR – compose a message of 3 strings: a, b, and c.
MSG composeMSTR (const char *a, const char *b, const char *c)
memset( (char *) &msg, 0, sizeof(msg) );
strcpy(msg.mStr.d[0],a);
strcpy(msg.mStr.d[1],b);
strcpy(msg.mStr.d[2],c);
return msg; }
// ——————————
// composeMINT – compose a message of 3 integers: a, b, and c.
MSG composeMINT (int a, int b, int c)
memset( (char *) &msg, 0, sizeof(msg) );
msg.mInt.d[0]= a; msg.mInt.d[1]= b; msg.mInt.d[2]= c;
return msg;
// ——————————
// composeMFLOAT – compose a message of 3 floating numbers: a, b, and c.
MSG composeMFLOAT (float a, float b, float c)
memset( (char *) &msg, 0, sizeof(msg) );
msg.mFloat.d[0]= a; msg.mFloat.d[1]= b; msg.mFloat.d[2]= c;
return msg;
// ——————————
void printFrame (const char *prefix, FRAME *frame)
webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc

3/18/22, 8:02 PM webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc
MSG msg= frame->msg;
printf (“%s [%s] “, prefix, KINDNAME[frame->kind]);
switch (frame->kind) {
printf (“‘%s’ ‘%s’ ‘%s'”,
msg.mStr.d[0], msg.mStr.d[1], msg.mStr.d[2]);
printf (“%d, %d, %d”,
msg.mInt.d[0], msg.mInt.d[1], msg.mInt.d[2]);
case FLOAT:
printf (“%f, %f, %f”,
msg.mFloat.d[0], msg.mFloat.d[1], msg.mFloat.d[2]);
case ACK: case DONE:
WARNING (“Unknown frame type (%d)\n”, frame->kind);
printf(“\n”);
// ——————————
int sendFrame (int fd, KIND kind, MSG *msg)
int len;
FRAME frame;
assert (fd >= 0);
memset( (char *) &frame, 0, sizeof(frame) );
frame.kind= kind;
frame.msg= *msg;
len= write (fd, (char *) &frame, sizeof(frame));
if (len == 0) WARNING (“sendFrame: sent frame has zero length. \n”);
else if (len != sizeof(frame))
WARNING (“sendFrame: sent frame has length= %d (expected= %d)\n”,
len, sizeof(frame));
return len; }
// ——————————
int rcvFrame (int fd, FRAME *framep)
int len;
FRAME frame;
assert (fd >= 0);
memset( (char *) &frame, 0, sizeof(frame) );
len= read (fd, (char *) &frame, sizeof(frame));
*framep= frame;
if (len == 0) WARNING (“rcvFrame: received frame has zero length \n”);
else if (len != sizeof(frame))
WARNING (“rcvFrame: received frame has length= %d (expected= %d)\n”,
len, sizeof(frame));
return len; }
// ——————————
// testDone: return 0 if all done flags are -1 (i.e., no client has started),
// or if at least one done flag is zero (i.e., at least one client
// is still working)
int testDone (int done[], int nClient)
webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc

3/18/22, 8:02 PM webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc
int i, sum= 0;
if (nClient == 0) return 0;
for (i= 1; i <= nClient; i++) sum += done[i]; if (sum == -nClient) return 0; for (i= 1; i <= nClient; i++) { if (done[i] == 0) return 0; } return 1; } // ------------------------------ int clientConnect (const char *serverName, int portNo) int sfd; struct sockaddr_in server; struct hostent *hp; // host entity // lookup the specified host hp= gethostbyname(serverName); if (hp == (struct hostent *) NULL) FATAL("clientConnect: failed gethostbyname '%s'\n", serverName); // put the host's address, and type into a socket structure memset ((char *) &server, 0, sizeof server); memcpy ((char *) &server.sin_addr, hp->h_addr, hp->h_length);
server.sin_family= AF_INET;
server.sin_port= htons(portNo);
// create a socket, and initiate a connection
if ( (sfd= socket(AF_INET, SOCK_STREAM, 0)) < 0) FATAL ("clientConnect: failed to create a socket \n"); if (connect(sfd, (SA *) &server, sizeof(server)) < 0) FATAL ("clientConnect: failed to connect \n"); return sfd; } // ------------------------------ int serverListen (int portNo, int nClient) int sfd; struct sockaddr_in sin; memset ((char *) &sin, 0, sizeof(sin)); // create a managing socket if ( (sfd= socket (AF_INET, SOCK_STREAM, 0)) < 0) FATAL ("serverListen: failed to create a socket \n"); // bind the managing socket to a name sin.sin_family= AF_INET; sin.sin_addr.s_addr= htonl(INADDR_ANY); sin.sin_port= htons(portNo); if (bind (sfd, (SA *) &sin, sizeof(sin)) < 0) FATAL ("serverListen: bind failed \n"); // indicate how many connection requests can be queued listen (sfd, nClient); webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc 3/18/22, 8:02 PM webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc return sfd; } // ------------------------------ void do_client (char *serverArg, int portNo) int i, len, sfd; char serverName[MAXWORD]; FRAME frame; MSG msg; struct timespec delay; strcpy (serverName, serverArg); printf ("do_client: trying server '%s', portNo= %d\n", serverName, portNo); sfd= clientConnect (serverName, portNo); printf ("do_client: connected \n"); delay.tv_sec= 0; delay.tv_nsec= 900E+6; // 900 millsec (this field can't be 1 second) for (i= 1; i < NITER; i++) { msg= composeMSTR ("Edmonton", "Red Deer", "Calgary"); len= sendFrame (sfd, STR, &msg); len= rcvFrame(sfd, &frame); printFrame("received ", &frame); msg= composeMINT (10, 20, 30); len= sendFrame (sfd, INT, &msg); len= rcvFrame(sfd, &frame); printFrame("received ", &frame); msg= composeMFLOAT (10.25, 20.50, 30.75); len= sendFrame (sfd, FLOAT, &msg); len= rcvFrame(sfd, &frame); printFrame("received ", &frame); printf ("----------\n"); nanosleep(&delay,NULL); msg= composeMINT(0,0,0); len= sendFrame (sfd, DONE, &msg); len= rcvFrame(sfd, &frame); printFrame("received ", &frame); printf("do_client: closing socket \n"); close(sfd); // ------------------------------ // do_sever: clients are numbered i= 1,2, ..., NCLIENT. void do_server () The done[] flags: done[i]= -1 when client i has not connected = 0 when client i has connected but not finished = +1 when client i has finished or server lost connection int i, N, len, rval, timeout, done[NCLIENT+1]; int newsock[NCLIENT+1]; char buf[MAXBUF], line[MAXLINE]; MSG msg; FRAME frame; struct pollfd pfd[NCLIENT+1]; struct sockaddr_in from; socklen_t fromlen; for (i= 0; i <= NCLIENT; i++) done[i]= -1; // prepare for noblocking I/O polling from the managing socket timeout= 0; webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc 3/18/22, 8:02 PM webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc pfd[0].fd= serverListen (MYPORT, NCLIENT);; pfd[0].events= POLLIN; pfd[0].revents= 0; printf ("Server is accepting connections (port= %d)\n", MYPORT); N= 1; // N descriptors to poll while(1) { rval= poll (pfd, N, timeout); if ( (N < NCLIENT+1) && (pfd[0].revents & POLLIN) ) { // accept a new connection fromlen= sizeof(from); newsock[N]= accept(pfd[0].fd, (SA *) &from, &fromlen); pfd[N].fd= newsock[N]; pfd[N].events= POLLIN; pfd[N].revents= 0; done[N]= 0; // check client sockets for (i= 1; i <= N-1; i++) { if ((done[i] == 0) && (pfd[i].revents & POLLIN)) { len= rcvFrame(pfd[i].fd, &frame); memset(line,0,MAXLINE); sprintf(line, "received from pollfd[i= %d]= %d (len= %d): ", i, pfd[i].fd, len); if (len == 0) { printf ("server lost connection with client\n"); done[i]= 1; continue; // start a new for iteration printFrame (line, &frame); if (frame.kind == DONE) {printf ("%s: Done\n", line); done[i]= 1;} sendFrame(pfd[i].fd, ACK, &msg); if (testDone(done,N-1) == 1) break; printf ("do_server: server closing main socket ("); for (i=1 ; i <= N-1; i++) printf ("done[%d]= %d, ", i, done[i]); printf (") \n"); for (i=1; i <= N-1; i++) close(pfd[i].fd); close(pfd[0].fd); // ------------------------------ int main (int argc, char *argv[]) if (argc < 2) FATAL ("Usage: %s [-c|-s] serverName \n", argv[0]); if ( strstr(argv[1], "-c") != NULL) { if (argc != 3) FATAL ("Usage: %s -c serverName \n"); do_client(argv[2],MYPORT); else if ( strstr(argv[1], "-s") != NULL) do_server(); webdocs.cs.ualberta.ca/~cmput379/W22/379only/sockMsg.cc 程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com