1 COMP445 Fall 2006 Lab assignment 1. 2 STEP1: Get the name of the second party STEP2: Get phone...

Preview:

Citation preview

1

COMP445COMP445Fall 2006Fall 2006

Lab assignment 1

2

STEP1: Get the name of the second party

STEP2: Get phone number from white pages

CALLER RECEIVER

STEP1: Plug the phone, and listen for incoming calls on a certain line

STEP3: Copy the number for your records

STEP4: Call the other party

ConnectionEstablished.

Chat…

STEP2: Get a call and accept it. “Caller ID” will give you the caller’s phone number.

3

Program architectureProgram architecture

ClientServerport 7070

4

Socket Programming

• Berkeley added a new interface to the operating system to support network communication. This interface is generally known as the Berkeley Sockets Interface and is the basis for almost all existing TCP/IP network protocol interfaces, including Windows Sockets

(commonly referred to as WinSock). • A socket is very much like a telephone - it's the endpoint

of a two-way communications channel. By connecting two sockets together you can pass data between

processes running on different computers.

5

Main steps – client sideMain steps – client sideCreating a socket

SOCKET socket(int domain, int type, int protocol);

s = socket(AF_INET,SOCK_STREAM,0)

The structure we fill in is defined below.

struct sockaddr_in { short sin_family; // address family u_short

sin_port;// service port struct in_addr 16 bit TCP or UDP port number, network byte order

sin_addr; // internet address char 32 bits IPv4 address, Network Bytes Order

sin_zero[8]; // filler

}sa_in

6

Main steps – client sideMain steps – client sideClient needs the address of the server.User inputs the server’s hostname.rp=gethostbyname(remotehost)

Fill in the server address memset(&sa_in,0,sizeof(sa_in)); memcpy(&sa_in.sin_addr,rp->h_addr,rp->h_length); sa_in.sin_family = rp->h_addrtype; sa_in.sin_port = htons(port); //port = 7070 host to network 16 bits

Connectingif (connect(s,(LPSOCKADDR)&sa_in,sizeof(sa_in)) == SOCKET_ERROR)

throw "connect failed\n"; Sending frames

ibytessent = send(s, (char*)&message_frame, sizeof(message_frame), 0);

Receiving frames

ibytesrecv = recv(s, (char*)& data_frame, sizeof(data_frame),0)

7

Main steps – server sideMain steps – server side

Creating a socket

s = socket(AF_INET,SOCK_STREAM,0)

Fill in the server port and address info

sa.sin_family = AF_INET;

sa.sin_port = htons(port);

sa.sin_addr.s_addr = htonl(INADDR_ANY);

Bind the server port if (bind(s,(LPSOCKADDR)&sa,sizeof(sa)) == SOCKET_ERROR)

Listen for client requests if(listen(s,10) == SOCKET_ERROR)

8

Main steps – server sideMain steps – server sideWatching for new messages

FD_SET(s,&readfds); //always check the listener if(!(outfds=select(infds,&readfds,NULL,NULL,tp))) {} else if (outfds == SOCKET_ERROR)

throw "failure in Select";

else if (FD_ISSET(s,&readfds))

cout << "got a connection request" << endl;

Accept the request

if((s1=accept(s,&ca.generic,&calen))==INVALID_SOCKET) throw "Couldn't accept connection\n";

Read a message

if((ibytesrecv = recv(s1,szbuffer,128,0)) == SOCKET_ERROR)

Send a message

if((ibytessent = send(s1,szbuffer,ibufferlen,0))== SOCKET_ERROR)

9

Socket Functions

• int socket(int family, int type, int protocol);

returns: nonnegative descriptor if OK, -1 on error

• int connect(int sockfd, const struct sockaddr * servaddr, int addrlen);

return:0 if OK -1 on error

• int bind(int sockfd, const struct sockaddr * myaddr, int addrlen);

return: 0 if OK, -1 on error

• int listen(int sockfd, int backlog);

return: 0 of OK, -1 on error

• int accept(int sockfd, struct sockaddr * cliaddr, int * addrlen);

returns: nonnegative descriptor if OK,-1 on error

10

CLIENT SERVERPURPOSE: File Transfer-Get a file-Send a file

•Should inform the server if the required action is to get a file from the server to upload a file to the server.•Should specify the name of theFile.•Respond to possible error messages.

•If a file is asked for, then it shouldsend an error message if file doesn’t exist.•If file exists, send it.•If file is being sent to you, save it.

11

Transferring the data in and Transferring the data in and from the packet structurefrom the packet structure

Struct CONTROL_FRAME {unsigned char direction; //GET or PUTchar fname[MAX]; //filename

}

struct MESSAGE_FRAME {unsigned char header; //ERROR,DATA,LASTPACKET, etc.char data[MAX_SIZE]; //data or error message

} message_frame;

YOU ARE FREE TO DESIGN YOUR OWN STRUCTURES

12

Reading from a fileReading from a filevoid main( void ) {

FILE *stream;

int numread, numwritten;

if( (stream = fopen( "fread.out", "r+b" )) != NULL ) {

numread = fread(message_frame.data,sizeof(char), MAX_SIZE, stream);

…}

else

printf( "File could not be opened\n" );

…}

fclose( stream );

}

Be careful if you use strcpy when reading from a binary file use memcpy.

13

Writing in a fileWriting in a filevoid main( void ) {

FILE *stream;

int numread, numwritten;

if( (stream = fopen( "fread.out", "w" )) != NULL ) {

numwritten = fwrite(szbuffer, sizeof(char), MAX_SIZE, stream );

…}

else{

printf( "Problem opening the file\n" );

…}

fclose( stream );

}

14

Decrypting the headerDecrypting the headerUse a switch to treat each of the cases:

switch (message_frame.header){   

case 1 : …;        break;   

case 2 : …;        break;   

case 3 : …;        break;

…………………………………………………………………………

default: …

}

15

HintsHints• Use a log file in each side in order to

monitor all the actions:– receiving a packet– sending a packet, etc.

• Open and close the log file after each read/write operation if your program freezes and you cannot read the log file.

• Do not use any string library function! You will be able to send only text files but not binary ones (jpeg or exe for example).

• Instead use memcpy for transferring data.• Do not care about the order of the receiving

packets in this assignment (TCP will do it for you).

16

Assignment 1

• No GUI

• Use Visual C++ 6

• Groups of NOT more than 2• wsock32.lib or you add the following

command to your code:#pragma comment(lib,"wsock32.lib")

• Implement only whatever you’re asked to do.

17

Multi-thread in Windows

uintptr_t _beginthread( void( __cdecl *start_address )( void * ), unsigned stack_size, void *arglist );

Parameters:

start_address

Start address of routine that begins execution of new thread.

stack_size

Stack size for new thread or 0.

arglist

Argument list to be passed to new thread or NULL.

18

The C++ Thread Class provided to you#define STKSIZE 16536class Thread{ public:Thread(){}

virtual ~Thread() {}static void * pthread_callback (void * ptrThis);virtual void run () =0 ;void start();

};

void * Thread::pthread_callback (void * ptrThis) { if ( ptrThis == NULL ) return NULL ; Thread * ptr_this =(Thread *)(ptrThis) ; ptr_this->run(); return NULL;} void Thread::start () { int result; if(( result = _beginthread((void (*)(void *))Thread::pthread_callback,STKSIZE,this ))<0)

{printf("_beginthread error\n");exit(-1);

} }

19

How to make _beginthread work in VC6.00++

Right click the project and go to the Setting->C/C++->Category. Change the Category to “Code Generation” and change Use run-time library to “Multithreaded”.Note:You will encounter such a error “error C2065: '_beginthread' : undeclared identifier” at the compile time if you don’t do the above setting.

Recommended