Skip to content

haoyangqian/Snowcast

Repository files navigation

Snowcast

Project in Computer Networks Course

Author:Haoyang Qian

Login:hqian1

###snowcast_server The server has three type of thread.

####Main thread Function:

  • accept user input and assign space for the global variable according to the numer of stations
  • initialize the stations information and create threads for every station
  • open socket to listen new connections from clients
  • handle user input like 'p'(print stations info) and 'q' (quit)

In order to handle stream both from listenfd and stdin at the same time,we use fd_set and select() function.First,we use FD_SET() function to assign listenfd and stdin as readable fd.Then,user select() to listen to both stream.When either stream receives an input,we can handle it.

In stdin,Server only accepts two input:'p' and 'q'.(1)'p':first lock the global variable of stations,print all the station info including the song name and the listening clients address and port.(2)'q' will close all the clients and release all the resourses then exit.

In listenfd,once select() finds a input from listenfd,which means a client is trying to connect to the server,we use accept() to connect this client.Then create a thread to handle this client.

####Station thread Number: every station have a thread

Function:

  • read music file
  • broadcast music to udp listener

In order to keep a rate of 16KiB/s,station should read the song file to buffer 16 times per second and every time the buffer length should be 1024KB.Before we send bytes to every clients,we clock time once to record the start time.Then after send() we clock the time again to record the end time,then you got the sendtime between start and end.Then use nanosleep() to sleep 1/16s - sendtime,which could keep a rate of 16KiB/S.

Once a music file is over,the thread should restart this song(using rewind()),and lock the station info then send announce to every client who is listening to this station.

When send to listeners,fisrt lock the station info,then iterate all the clients in the linked list then send buffer to the udpPort of every client.

####Client thread Number:every client have a thread

Function:

  • receive command from clients and send command to clients
  • set station for every client
  • receive invalid command and return invalid reply

First,thread receive HELLO command from client,then return a WELCOME command with the total number for stations.

Second,thread wait for a SET_STATION command,after successfully received the correct SET_STATION command,thread call unset_station() first to remove the client from the previous station(if there's no station this client is listening,do nothing),then call set_station() to add this client to the new station.In both unset_station() and set_station() ,thread would lock the stations variable to pretect the shared data.

After successfully set to a new station.thread send a ANNOUNCE command with the song name to the client.

####Invalid command Thread use state value and return types to prevent Invalid command and wrong order of command, we have DEFAULT,WAIT_WEL,WAIT_ANC,RCV_ANC which indicates different state of client thread.And we have DUP_HELLO,INVALID_CMD,CLI_CLOSE,WRONG_STATIONwhich indicates the different types of return value.

For example,if a thread receive a HELLO when it is supposed to receive a SET_STATION,it will return a DUP_HELLO error and close the connection.And if the station number which received from client is not in range of the server's station number,it will return a WRONG_STATIONNUM eroor and send the INVALID_COMMAND to client,then close the connection to this client.

####Timeout Server check timeout when receive part of command from client.

When receving HELLO or SET_STATION,thread found that the bytes received is less than the bytes we expected,then it calls poll() to wait for the other bytes,and if it does not receive the other bytes in one particular time(We set it to 100ms),then we timeout this connection,print error and close the connection.

And we will also timeout the connection that if the client is not sending HELLO to the server in a particular time (We set it to 100ms) after the connection was build.

###snowcast_controller Function:

  • connect to the server and send HELLO command
  • receive WELCOME command and get the number of stations
  • accept user input to set a station number and send SET_STATION command to server
  • receive ANNOUNCE command from server

First,receive the arguments as hostname, portNumber, udpPort.Use open_client() to create socket and connect to Server,and return the sockfd.After connecting to the server Successfully,use send_hello() to send a HELLO command to Server.After sending HELLO,controller should receive WELCOME from Server using recv_welcome().

In order to handle stream both from sockfd and stdin at the same time,we use fd_set and select() function. From stdin stream we only accept number or 'q'.After user entered a valid number for station,call send_station() to send command to the server.From sockfd stream,controller receive the ANNOUCE or INVALID_COMMAND_REPLY by recv_string().

####Invalid command We have DEFAULT,WAIT_WEL,WAIT_ANCto represent the state for controller.

When we receive any command with replytype other than '0'or'1'or'2',we return a unknown response error and close the connection.when we receive a command with replytype 2,we print the replystring and close the connection. ####Timeout Like the server,controller will timeout the connection when receive part of command.

When receving WELCOME,controller found that the bytes received is less than the bytes we expected,then it calls poll() to wait for the other bytes,and if it does not receive the other bytes in one particular time(We set it to 100ms),then we timeout this connection,print error and close the connection.

when receiving ANNOUNCE or INVALID_COMMAND_REPLY,controller first reveive 2 bytes of the buffer to get the expected length of this message,then check if the received bytes is less than expected,if so,it calls poll() to wait for the other bytes,and if it does not receive the other bytes in one particular time(We set it to 100ms),then we timeout this connection,print error and close the connection.

###snowcast_listener Function:

  • receive the music from server and write them to stdout
  • keep the rate as 16KiB/S

Receive the arguments as udpPort.Use open_client() to create socket and bind this socket to udpPort.Receive Bytes from Server continuiously and write them to stdout.

To keep the rate as 16KiB/S,use the same way as server does.

About

Project in Computer Networks

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published