Skip to content

Instantly share code, notes, and snippets.

@moonblade
Last active November 20, 2016 17:01
Show Gist options
  • Save moonblade/f3d86960bf2e8a48b46f08e4bdeddead to your computer and use it in GitHub Desktop.
Save moonblade/f3d86960bf2e8a48b46f08e4bdeddead to your computer and use it in GitHub Desktop.
osLab
#include <iostream>
/*Socket obviously required*/
#include <sys/socket.h>
/*Any shit ending with _t is prolly from this library*/
#include <sys/types.h>
#include <string>
#include "string.h"
#include "unistd.h"
#include "netinet/in.h"
#define defPort 142536
#define defPortDgram 253614
#define max 256
using namespace std;
/*Some random class to send and receive as a class instead of as simple character stream*/
class mail
{
public:
char *to,*from,*message;
mail(char* a,char* b,char* c): from(a),to(b),message(c){};
void print()
{
cout<<endl;
cout<<"from :"<<from<<endl;
cout<<"to :"<<to<<endl;
cout<<"message :"<<message<<endl;
cout<<endl;
}
};
// To exit out of program on error, should be pretty easy to understand
void exitError(string error)
{
cout<<error<<endl;
exit(-1);
}
/*To use as parent class for stuff that uses datagram socket*/
class datagramSocketEndPoint
{
protected:
/*Dsock is the socket descriptor*/
int dsock;
/*Buffer is made void * so that it can even point to random class objects if needed*/
void *buf;
sockaddr_storage returnAddress;
public:
datagramSocketEndPoint()
{
/*Initialise a datagramsocket*/
buf = new char[max];
dsock = socket(AF_INET,SOCK_DGRAM,0);
if (dsock<0)
exitError("cannot create datagramSocket");
}
/*Send data*/
void sendd(void *data,int size,sockaddr *destinationAddress)
{
/*man pages are your friend*/
sendto(dsock,data,size,0,destinationAddress,sizeof(sockaddr_in));
}
/*receive a buffer from sockfd*/
void received(int type)
{
socklen_t dummy = sizeof(sockaddr_in);
switch(type)
{
/*Receive normal character stream*/
case 0:
/*Since buffer is void*, cast is used to convert to character*/
recvfrom(dsock,buf,max,0,(sockaddr *)&returnAddress,&dummy);
cout<<(char *)buf;
break;
}
}
};
/*Superclass for classes that use streamsockets*/
class streamSocketEndPoint
{
protected:
/*buffer is used to send data, and sockfd is socket descriptor*/
int sockfd;
void *buf;
public:
/*initialise buffer and socket descriptor*/
streamSocketEndPoint()
{
buf = new char[max];
/*man socket (or man 2 socket in some systems to know what each are)*/
sockfd=socket(AF_INET,SOCK_STREAM,0);
if (sockfd<0)
exitError("cannot create socket");
}
/*Send data*/
void send(void *data,int size)
{
write(sockfd,data,size);
}
/*receive a buffer from sockfd*/
void receive(int type=0)
{
switch(type)
{
/*Receive normal character stream*/
case 0:
/*Since buffer is void*, cast is used to convert to character*/
read(sockfd,buf,max);
cout<<(char *)buf;
break;
/*Receive a class object*/
case 1:
read(sockfd,buf,sizeof(mail));
((mail *)buf)->print();
break;
}
}
~streamSocketEndPoint()
{
close(sockfd);
}
};
/*Sender class is the server
server will bind the address, listen to it, and when accepting a
connection will create a new client socket so that the listening socket is not interupted
*/
class sender : public streamSocketEndPoint, public datagramSocketEndPoint
{
public:
/*bind and listen, accept*/
sockaddr_in mybind(int port,int &socket)
{
/*Create a sockaddr_in type, with the same family and given port*/
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
saddr.sin_addr.s_addr=htonl(INADDR_ANY);
/*try and bind the sockfd to it*/
if(bind(socket,(sockaddr *)&saddr,sizeof(saddr))<0)
exitError("Cannot bind socket");
return saddr;
}
void bnla(int port)
{
sockaddr_in saddr=mybind(port,sockfd);
/*Listen for incoming connection (only 1 parallel connection given)*/
listen(sockfd,1);
/*dummy, not required later*/
socklen_t dummy = sizeof(sockaddr_in);
/*overwriting socket for client via accept
REALLY REALLY BAD, DONT DO LIKE THIS, MAKE A NEW SOCKET
man 2 accept for details
*/
sockfd = accept(sockfd,(sockaddr *)&saddr,&dummy);
}
void bnlad(int port)
{
sockaddr_in saddr=mybind(port,dsock);
}
sockaddr* getClientAddress(int port)
{
return (sockaddr *) &areturnAddress;
}
};
/*Receiver class or client class will connect to server and send data*/
class receiver : public streamSocketEndPoint, public datagramSocketEndPoint
{
public:
/*Try and connect to server port*/
void con(int port)
{
/*sock addr data type, add port and family, connect*/
sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
saddr.sin_addr.s_addr=htonl(INADDR_ANY);
if(connect(sockfd,(sockaddr *)&saddr,(socklen_t)sizeof(saddr))<0)
exitError("cannot connect");
}
sockaddr_in getServerAddress(int port)
{
/*sock addr data type, add port and family*/
sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
saddr.sin_addr.s_addr=htonl(INADDR_ANY);
return saddr;
}
};
/*driver program for above*/
int main(int argc, char const *argv[])
{
char opt='s';
if(rand()%5==0)
{
cout<<"Server or Client (s/C)?: ";
cin>>opt;
if(opt!='s')
{
/*Init receiver*/
receiver r;
/*Connect to port*/
r.con(defPort);
/*Single one send*/
char a[20]="data from client";
r.send(a,strlen(a));
/*Single one receive*/
r.receive();
/*Send object instead of char stream*/
mail *m = new mail("[email protected]","[email protected]","message is message");
r.send(m,sizeof(mail));
}
else
{
/*init sender*/
sender s;
/*bind, listen accept from port*/
s.bnla(defPort);
/*Single one receive*/
s.receive();
// Single one send
char a[20]="data from server";
s.send(a,strlen(a));
/*Receive mail (type 1 message)*/
s.receive(1);
}
}
else
{
cout<<"Server or Client (s/C)?: ";
cin>>opt;
if(opt!='s')
{
/*STREAM SOCKET*/
/*Init receiver*/
receiver r;
/*DATAGRAM SOCKET*/
sockaddr_in server = r.getServerAddress(defPortDgram);
char a[20]="data from client";
r.sendd(a,strlen(a),(sockaddr*) &server);
r.received(0);
}
else
{
/*init sender*/
sender s;
/*DATAGRAM SOCKET*/
s.bnlad(defPortDgram);
s.received(0);
sockaddr *client = s.getClientAddress(defPortDgram);
char a[20]="data from server";
s.sendd(a,strlen(a),client);
}
}
return 0;
}
// Iostream for obvious reasons
#include<iostream>
// Has important types stuff thats used throughout the programs, say pid_t, or size_t etc etc
#include<sys/types.h>
// For getting POSIX (unix like) functions, you know like pipe, fork, essentially system call features
#include<unistd.h>
// String stuff
#include<string.h>
// Math stuff
#include<math.h>
using namespace std;
/*Whenever a forked process calls the print function, it passes the fork number to it, to avoid confusion.
The print function prints the details of the current fork*/
void print(int control)
{
/*The process number or fork number*/
string name="process "+to_string(control);
/*Process Id, id of process that will be shown in ps ax command in linux*/
cout<<name<<" pid "<<getpid()<<endl;
/*Parent Process Id, Id of process that spawned the current process, for the initial process, parent id is 0*/
cout<<name<<" ppid "<<getppid()<<endl;
/*User and group id of the user that is running the current process (your login and which group your login belongs to)*/
cout<<name<<" uid "<<getuid()<<endl;
cout<<name<<" egid "<<getegid()<<endl;
cout<<endl;
}
int main()
{
pid_t pid,pid2,pid3,par = getpid();
int mul=0;
/*Fork() makes two process, one the original process fork returns the parent process id
if pid==0, child process, else parent process (depends on machine, may invert in some machines)
1---+
| |
2 3
|
4
can be done by
fork (gets 1 and 2)
if parent(ie 1)
fork again (1 and 3)
if child (3)
fork again (3 and 4)
so any tree structure can be made
The tree is confirmed using parent pids
*/
pid = fork();
if(pid)
{
// Parent process
pid2=fork();
if(pid2)
print(1);
else
{
pid3=fork();
if(pid3)
print(2);
else
print(3);
}
}
else
{
print(4);
}
}
/*Create a program that prints a and b such that there are no three a's or three b's at the same time*/
/*It can also be viewed as a Producer consumer problem with max size 2*/
#include<iostream>
/*For semaphore shit*/
#include<semaphore.h>
#include<pthread.h>
#include<fcntl.h>
#include<stdio.h>
using namespace std;
/*Make two semaphores a and b, since the maximum occurance together is 2,
init one of them with 2 and other with 0 (2,0 or 1,1 or 0,2)
when one is over, signal the other
wait a
do shit for a
signal b
will be the code
*/
sem_t *sema,*semb;
/*a will wait for itself, but signal the other one*/
void *workera(void *args)
{
/*Infinite loop, wait a, do a, signal b*/
while(1)
{
sem_wait(sema);
cout<<"a";
sem_post(semb);
}
}
void *workerb(void *args)
{
/*Infinite loop, wait b, do b, signal a*/
/*Thus the maximum sema or semb can get is 2, hence at most 2 a or 2 b occur together*/
while(1)
{
sem_wait(semb);
cout<<"b";
sem_post(sema);
}
}
int main()
{
/*Initialise semaphores after allocating memory*/
sema = (sem_t*) malloc(sizeof(sem_t));
semb = (sem_t*) malloc(sizeof(sem_t));
/*Sucks to be you, can't init shit*/
pthread_t a,b;
if(sem_init(sema,0,1)==-1)
{
cout<<"Error";
}
else
{
if(sem_init(semb,0,1)==-1)
{
cout<<"Error";
}
else
{
/*Start your enignes*/
pthread_create(&a,NULL,&workera,NULL);
/*Go go go*/
pthread_create(&b,NULL,&workerb,NULL);
/*Wont stop ever so pointless*/
pthread_exit(NULL);
}
};
}
#include <iostream>
#include <string>
#define max 30
#define ws 8
using namespace std;
/*
Sliding window class is used to simulate a window where the acknowledgements to be received at the sender side are kept
Sliding window operations are
Add acknowledgement packet:
Add a packet with a certain acknowledgement number onto the window
Acknowledge packet:
When a packet is ackowledged, it is deleted from the sliding window
slide window:
|0|0|3|0|5|6|0|
^
|
first non acknowledged packet is here, so sliding window can be slid two spaces to give
|3|0|5|6|0|0|0|
Thus making space for new packets at the end
find first non acknowledged packet:
the done() function finds the packet yet to be acknowledged and sends its index(in sliding window) and the actual acknowledgement number as a pair
if all packets are acknowledged, it returns 0, ie window can be slid entirely
resend():
in selective repeat only frames that are not acknowledged are resent again, so a resend funciton checks if given acknowledge frame is empty or not
|0|0|0|4|
resend(1) => false
resend(4) => true
*/
class slidingWindow
{
public:
int *q;
int shift;
int size;
slidingWindow(int size)
{
this->size=size;
q=new int[size];
}
slidingWindow()
{
this->size=ws;
q=new int[size];
shift=0;
for(int i=0;i<size;++i)
q[i]=0;
}
void add(int a)
{
q[(a-shift)%size]=a;
}
void ack(int a)
{
q[(a-shift)%size]=0;
}
void shif(int s)
{
shift+=s;
}
/*The index of the first acknowledge number not acknowledged(in the window)+1, and the acknowledge number*/
/*0 is reserved for all acknowledged*/
pair<int,int> done()
{
for(int i=0;i<size;++i)
{
if(q[i]!=0)
return *new pair<int,int>(i+1,q[i]);
}
return *new pair<int, int>(0,0);
}
bool resend(int a)
{
return q[(a-shift)%size]!=0;
}
};
/*
Receiver is a simple class used only as a medium to receive data and randomly decide on either sending or not sending ack
Both data and its index (which is the ack) is sent, it randomly either sends ack back or sends -1 (NACK - negative acknowledgement)
*/
class receiver
{
public:
int receive(int a,int ack)
{
cout<<"Receiver : "<<"Received value "<<a<<" with ack "<<ack<<endl;
if(rand()%3)
{
cout<<"Receiver : "<<"Sending acknowledge : "<<ack<<endl;
return ack;
}
else
{
cout<<"Receiver : "<<"Sending no acknowledge"<<endl;
return -1;
}
}
};
/*
In its constructor sender initialises an array called data which is the data to be sent to receiver
Stop and Wait
-------------
Stop and wait and go back n are essentially the same with the difference that stop and wait has window size 1
Each packet waits for its acknowledgement, if ack received, next packet is sent, else the same packet is resent,
Go back N
---------
A window of size t is kept
t packets are sent simultaneously
1|2|3|4|5|6|7|8 <-- sliding window
The packets that are acknowledged are eliminated
0|0|3|0|0|6|0|8 <-- sliding window after ack
The sliding window is slid till the first non acknowledged packet
|3|0|0|6|0|8|0|0 <-- new sliding window
all the elements in the sliding window are sent again
|3|4|5|6|7|8|9|10 <-- new sliding window
Selective repeat
----------------
A window of size t is kept
t packets are sent simultaneously
1|2|3|4|5|6|7|8 <-- sliding window
The packets that are acknowledged are eliminated
0|0|3|0|0|6|0|8 <-- sliding window after ack
The Ones that are non acknowledged are sent again till ack is reached
0|0|0|0|0|0|0|8 <-- sliding window after ack (8 still did not get ack resend 8)
0|0|0|0|0|0|0|0 <-- sliding window after ack final
entire sliding window is shifted
|0|0|0|0|0|0|0|0 <-- sliding window after ack final
*/
class sender
{
public:
int data[max];
/*Data init as multiples of 5*/
sender()
{
for(int i=0;i<max;++i)
{
data[i]=(i+1)*5;
}
}
/*Selective repeat ARQ*/
void selectiveRepeat(receiver r)
{
cout<<"Simulation of Selective Repeat sliding window protocol"<<endl;
cout<<"------------------------------------------------------"<<endl;
/*Sent is the index till which sending has been done
When sent==max, completed*/
int sent=0;
/*Create a sliding window os size WINDOWSIZE (ws)*/
slidingWindow s;
/*This boolean flag is used to check if entire window is slid and next 8 data can be sent simultaneously, since at the beginnig there is no ack to be received next 8 data can be sent, and this bool is set to true*/
bool next=true;
while(sent<max)
{
/*Whether or not entire window is to be slid, if there is a non ack member, this is made false*/
bool slide=true;
if(next)//ie send the next data
{
/*Sent one window size amount of data and acknowledge(remove from window) the ones that were acknowledged*/
next=false;
for(int j=0;j<ws && j+sent<max;++j)
{
s.add(sent+j);
cout<<"Sender : "<<"Sent data : "<<data[sent+j]<<endl;
int ack=r.receive(data[sent+j],sent+j);
if(ack!=-1)
{
s.ack(ack);
}
}
}
/*For the ones in sliding window*/
for(int j=0;j<ws && j+sent<max;++j)
{
/*If no acknowledge was received, ie it has to be resent?*/
if(s.resend(j+sent))
{
/*Resend the single data frame and check if ack came again*/
slide=false;
cout<<"Sender : "<<"Resending data : "<<data[sent+j]<<endl;
int ack=r.receive(data[sent+j],sent+j);
if(ack!=-1)
{
s.ack(ack);
}
}
}
auto k = s.done();
if(k.first==0)
{
/*If all the frames in the window are acknowledged slide the entire window, In selective repeat, only entire sliding has been done*/
if(slide)
{
cout<<"Sender : "<<"Sliding entire window"<<endl;
s.shif(s.size);
sent+=s.size;
next=true;
}
}
/*If at least one is not acknowledged, same window is kept and data is resend till ack is received and window is completely acknowledged*/
}
}
/*Go back N ARQ*/
void goBackN(receiver r)
{
cout<<"Simulation of go back N sliding window protocol"<<endl;
cout<<"-----------------------------------------------"<<endl;
int sent=0;
/*None sent yet, sliding window of size ws*/
slidingWindow s;
while(sent<max)
{
/*Send ws amount of data together and acknowledge the ones that get ack back*/
for(int j=0;j<ws && j+sent<max;++j)
{
s.add(sent+j);
cout<<"Sender : "<<"Sent data : "<<data[sent+j]<<endl;
int ack=r.receive(data[sent+j],sent+j);
if(ack!=-1)
{
s.ack(ack);
}
}
/*Find the first non acknowledged frame*/
auto k = s.done();
/*If the first non acknowledged frame is not the first frame, then window can be shifted be that amount*
|0|0|3|4|5|6|0| <- shift by two to get
|3|4|5|6|0|0|0| <- shift by two to get
*/
if(k.first>1)
{
cout<<"Sender : "<<"Sliding window by "<<k.first-1<<endl;
s.shif(k.first-1);
sent+=k.first-1;
}
/*If the first frame is not ack, can't shift, do nothing
|1|0|3|4|5|6|0| <- No shift */
else if(k.first==1)
{
cout<<"Sender : "<<"Resending"<<endl;
}
/*Everything ack, shift entire window
|0|0|0|0|0|0|0| <- full shift
|0|0|0|0|0|0|0| <- final result
*/
else if(k.first==0)
{
cout<<"Sender : "<<"Sliding entire window"<<endl;
s.shif(s.size);
sent+=s.size;
}
}
}
void sendStopAndWait(receiver r)
{
/*Go back N with sliding window size as 1*/
cout<<"Simulation of stop and wait sliding window protocol"<<endl;
cout<<"---------------------------------------------------"<<endl;
int sent=0;
/*only one element in window*/
slidingWindow s(1);
while(sent<max)
{
/*Send one, wait for ack, ack if received*/
s.add(sent);
cout<<"Sender : "<<"Sent data : "<<data[sent]<<endl;
int ack=r.receive(data[sent],sent);
if(ack==-1)
{
cout<<"Sender : "<<"No ack Received, resending"<<endl;
}
else
{
s.ack(ack);
}
auto k = s.done();
/*This wont execute since k.first = 0 or 1*/
if(k.first>1)
{
cout<<"Sender : "<<"Sliding window by "<<k.first<<endl;
s.shif(k.first);
sent+=k.first;
}
/*No ack*/
else if(k.first==1)
{
cout<<"Sender : "<<"Resending"<<endl;
}
/*Ack got, shift by one
|0| init
|0| final
*/
else if(k.first==0)
{
cout<<"Sender : "<<"Sliding entire window"<<endl;
s.shif(s.size);
sent+=s.size;
}
}
}
};
int main(int argc, char const *argv[])
{
sender s;
receiver r;
s.sendStopAndWait(r);
s.goBackN(r);
s.selectiveRepeat(r);
return 0;
}
/*Same as socket program, but instead fill the buffer with parts of file and regurgitate into a file at the other side*/
//Converted both server and client into a single program, so use as ./12 s filename or ./12 c filename
#include<iostream>
#include<stdio.h>
#include<sys/types.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<fstream>
#define sa struct sockaddr
#define listenq 5
#define defport "132445"
using namespace std;
class receiver
{
public:
char* filename;
char* port;
receiver(char* filename, char* port)
{
this->filename = filename;
this->port = port;
}
void receive()
{
int fd,sockfd,listenfd,connfd;
pid_t childpid;
socklen_t client;
struct sockaddr_in servaddr, cliaddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port = htons(atoi(this->port));
bind(listenfd,(sa*)&servaddr,sizeof(servaddr));
listen(listenfd,listenq);
client=sizeof(cliaddr);
connfd=accept(listenfd,(sa*)&cliaddr,&client);
char buffer[100];
bzero(buffer,sizeof(buffer));
ofstream f(filename);
buffer[0]='r';
while(buffer[0]!='\0')
{
read(connfd,buffer,100);
f<<buffer;
f<<'\n';
}
f.close();
printf("the file received");
}
};
class sender
{
public:
char *filename;
char *port;
sender(char *filename, char *port)
{
this->filename = filename;
this->port = port;
}
void send()
{
int sockfd;
char fname[25];
int len;
struct sockaddr_in servaddr,cliaddr;
sockfd=socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(atoi(this->port));
inet_pton(AF_INET,this->port,&servaddr.sin_addr);
connect(sockfd,(sa*)&servaddr,sizeof(servaddr));
char buffer[100];
ifstream f(filename);
while(f.getline(buffer,sizeof(buffer)))
write(sockfd,buffer,100);
char end='\0';
memcpy(buffer,&end,1);
write(sockfd,buffer,100);
f.close();
cout<<"sent"<<endl;
}
};
int main(int argc, char **argv)
{
if(argc<3)
{
cout<<"usage : netcat s/c filename [port]"<<endl;
}
//cout<<argv[1];
if (argv[1][0]=='s')
{
// cout<<"sender";
char port[10] = defport;
if(argc>3)
strcpy(port,argv[3]);
// cout<<port;
sender s(argv[2],port);
s.send();
}
else
{
// cout<<"receiver";
char port[10] = defport;
if(argc>3)
strcpy(port,argv[3]);
// cout<<port;
receiver r(argv[2],port);
r.receive();
}
return 0;
}
//Same as socket, use udp (so slight syntax changes)
//pass an object instead of random data
//server
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
struct mail{
char from[255],to[255],subject[1024],content[1024];
};
int main(int argc,char **argv){
int udpSocket, nBytes;
char buffer[255];
struct sockaddr_in servaddr, cliaddr;
struct sockaddr_storage servsto;
socklen_t addr_size, cli_size;
int i;
udpSocket=socket(PF_INET,SOCK_DGRAM,0);
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(atoi(argv[1]));
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
memset(servaddr.sin_zero,'\0',sizeof(servaddr.sin_zero));
bind(udpSocket,(struct sockaddr *)&servaddr,sizeof(servaddr));
addr_size=sizeof(servsto);
struct mail m;
nBytes=recvfrom(udpSocket,&m,sizeof(m),0,(struct sockaddr *)&servsto,&addr_size);
cout<<"FROM :" <<m.from<<endl;
cout<<"TO: "<<m.to<<endl;
cout<<"SUBJECT: "<<m.subject<<endl;
cout<<"CONTENT: "<<m.content<<endl;
bzero(buffer,255);
strcpy(buffer,"recieved");
sendto(udpSocket,buffer,9,0,(struct sockaddr *)&servsto,addr_size);
return 0;
}
//client
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
struct mail{
char from[255],to[255],subject[1024],content[1024];
};
int main(int argc, char **argv){
int cliSocket, portNum, nBytes;
char buffer[255];
struct sockaddr_in servaddr;
socklen_t addr_size;
cliSocket=socket(PF_INET,SOCK_DGRAM,0);
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(atoi(argv[1]));
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
memset(servaddr.sin_zero,'\0',sizeof(servaddr.sin_zero));
addr_size=sizeof(servaddr);
struct mail m;
cout<<"FROM: ";
cin.getline(m.from,255);
cout<<"TO: ";
cin.getline(m.to,255);
cout<<"SUBJECT: ";
cin.getline(m.subject,1024);
cout<<"content: ";
cin.getline(m.content,1024);
sendto(cliSocket,&m,sizeof(m),0,(struct sockaddr *)&servaddr,addr_size);
nBytes=recvfrom(cliSocket,buffer,255,0,NULL,NULL);
cout<<buffer;
return 0;
}
// Pipe original program, send array and find primes in them, assuming you know normal pipes, instead of one data, first send size then send array then find primes in them on the receieving side
#include<sys/types.h>
#include<iostream>
#include<unistd.h>
#define max 10
using namespace std;
/*check if n is prime */
int isprime(int n)
{
if(n<2)
return 0;
if(n==2)
return 1;
for(int i=2; i<=n/2; i++)
if(n%i==0)
return 0;
return 1;
}
//print inside a process, so process id and a number to print is given
void print(int p, int &n)
{
cout<<p<<" says : "<<n<<"\n";
}
// Print all primes in an array, also print pid
// combination of above two
void printprimes(int p,int a[],int s)
{
for(int i=0;i<s;++i)
if(isprime(a[i]))
print(p,a[i]);
}
// function to exit
void er()
{
cout<<" Pipe not created ";
exit(0);
}
// Read number in process p
void read(int p, int &n)
{
cin>>n;
}
int main()
{
// P is used for storing process number
int p;
// A two integer size array will be used as our pipe
int fd[2];
// Here size of the data is passed
int size[2];
// make pipe of both
if(pipe(fd)==-1)
{
er();
return 0;
}
if(pipe(size)==-1)
{
er();
return 0;
}
// make two processes
p=fork();
if(p)
{
//parent
// close first part
close(fd[0]);
close(size[0]);
// send size
cout<<"1 asks enter n : ";
int a[max],n;
cin>>n;
write(size[1],&n,sizeof(int));
// send array
cout<<"1 asks enter elements : ";
for(int i=0;i<n;++i)
cin>>a[i];
write(fd[1],a,n*sizeof(int));
}
else
{
//child
// close second half
close(fd[1]);
close(size[1]);
int b[max],c;
// get size
read(size[0],&c,sizeof(int));
// get array
read(fd[0],b,c*sizeof(int));
// print the primes
printprimes(2,b,c);
}
return 0;
}
// Minimal program for pipes, send a number
#include<sys/types.h>
#include<iostream>
#include<unistd.h>
#define max 10
using namespace std;
int main()
{
// p is used to check if fork is parent or child
pid_t p;
// file descriptor of two integer length array, this will serve as the pipe between processes
// first process |x| | ---> | |x| second process
// first part of array of first process(i/p), and second part of array of second process(o/p) is not used
// first process disables the fd[0], and copies data to fd[1]
// second process disables fd[1] and reads data from fd[0]
int fd[2];
// Make the fd into a pipe, if fail exit
if(pipe(fd)==-1)
{
// no pipe
return 0;
}
// Fork to create two processes
p=fork();
if(p)
{
//parent
close(fd[0]);
int n=20; //data to transmit
// Write data to fd[1] of pipe (o/p part)
write(fd[1],&n,sizeof(int));
// write(fd[1],array,sizeof(int)*arraysize); to write array
}
else
{
//child
close(fd[1]);
int c;
// Read data from fd[0] of pipe (i/p part)
read(fd[0],&c,sizeof(int));
// read(fd[0],array,sizeof(int)*arraysize); to read array
cout<<c;
}
return 0;
}
#include<iostream>
#include<unistd.h>
#include<sys/shm.h>
#include<sys/wait.h>
#include<sys/ipc.h>
#include<string.h>
#define max 20
using namespace std;
/*
All these can be found from man pages
man <function name> will give the parameters required, try it out
shmget, shared memory create
params - IPC_PRIVATE,size, flag(for permission, 0666)
returns the pointer to base address
shmat - give address to attach to same memory location
shmat(id,NULL,0)
shmdt - detach
shmctl, to change permissions, analogues to chmod
wait(NULL)
*/
// shmget, shmat, shmdt, shmctl
// Error function
void er()
{
cout<<"Could not get shared memory";
}
// Print from a given process id,
// 1 says : my message
void say(int pid,char* message)
{
cout<<pid<<" says : "<<message;
}
int main()
{
// for forking
pid_t p;
// Create an shared memory id, using a predetermined key, here key used is IPC_PRIVATE
// size is max characters, 0666 is permissions
int shmid=shmget(IPC_PRIVATE,max*sizeof(char),0666);
// die if can't create
if(shmid==-1)
{
er();
return 0;
}
// Fork to spawn child process
p = fork();
if(!p)
{
// In child process
// Get address of shared memory character (or string)
char *p=(char *)shmat(shmid,NULL,0);
// Copy data there
cin>>p;
}
else
{
// In parent
// Since shared memory is not blocking, we use wait null to wait till all children are finished
wait(NULL);
// get shared memory address
char *get=(char *)shmat(shmid,NULL,0);
// print it
say(2,get);
}
return 0;
}
// ipc using message queues
#include<iostream>
// For sleep command (might not be used in this)
#include<sys/wait.h>
// Posix shit
#include<unistd.h>
// Inter Process Communication, some shit like msgbuf maybe?
#include<sys/ipc.h>
// For message queue specific shit
#include<sys/msg.h>
#include<string>
#include<string.h>
#define max 20
using namespace std;
// Messages have a specific structure, they should be a long (message type number) and a char array of
// the actual message
// The names msgbuff, mtype and mbuff can be any shit
struct msgbuff
{
long mtype;
char mbuff[max];
};
// Print with process id and string
// glorified PA System, process 1 says : blah blah
void say(string a, string b)
{
cout<<a<<" Says : "<<b;
}
int main()
{
// This will be the message q id
int msgq;
// Message q id is generated with a preshared key, this key is given to every participant and the id
// is generated with this key with msgget()
key_t k=123;
// Flags, create if not exist and other permissions needed
int msgflag=IPC_CREAT|0666;
// Get the q id from the flag and key
msgq=msgget(k,msgflag);
//private only owner, EXCL exclusive only one guy gets, CREAT create if not exist flags are also available
pid_t p;
//fork the shit out of it
p=fork();
if(!p)
{
// Message queue is not blocking, the queue will get filled as you add more messages, and will
// clear as you collect, works like a stream in cpp
say("1","started\n");
//Create a msg buffer
msgbuff a;
// read data into the message buffer, of message type 1
msgrcv(msgq,&a,sizeof(a.mbuff),1,0);
// print it
say("1",a.mbuff);
say("1","ended\n");
return 0;
}
else
{
// sender
say("2","started\n");
// message buffer
msgbuff a;
// of type 1 messages
a.mtype=1;
// add message
strcpy(a.mbuff,"Hello World\n");
// send it
msgsnd(msgq,&a,sizeof(a.mbuff),0);
say("2","ended\n");
}
return 0;
}
/*Addendum: Randomly goes haywire when cin is used instead of an automated loop as given, when a chat
application is made it randomly decides not to send any data and there has been no fix so far, some
found the same code to work perfectly on some machines*/
#include<iostream>
#include<sys/types.h>
// needed shit
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<unistd.h>
#include<string.h>
using namespace std;
int main(){
int sockfd,newsockfd,portno,n;
socklen_t serv_len;
struct sockaddr_in servAddr;
char buffer[256];
// make a socket
portno=20009;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0){
cout<<"ErroropeningSocket!";
return 0;
}
// need server address in servAddr
bzero( (char*)&servAddr , sizeof(servAddr) );
servAddr.sin_family=AF_INET;
servAddr.sin_port=htons(portno);
// Try to connect to server
if( connect( sockfd, (struct sockaddr*)&servAddr ,sizeof(servAddr) ) <0 )
cout<<"connecctionErrror";
// Keep sending messages
while(1){
cout<<"Enter the Message: ";
bzero(buffer,256);
cin>>buffer;
n=write(sockfd,buffer,strlen(buffer));
if(n<0){
cout<<"ErrorWritingToSocket";
return 0;
}
bzero(buffer,256);
n=read(sockfd,buffer,255);
cout<<"message: "<<buffer<<endl;
}
close(sockfd);
return 0;
}
#include<sys/types.h>
// For shit on sockets
#include<sys/socket.h>
#include<iostream>
// This
#include<netdb.h>
// And this are also required
#include<netinet/in.h>
#include<string.h>
#include<unistd.h>
using namespace std;
// Socket involves a lot of mugging up
int main(){
// Socket discriptors to be used
int sockfd,newsockfd,portno,n;
// Socklength type for length of client storage
socklen_t clilen;
// buffer to haul data
char buffer[256];
struct sockaddr_in servAddr,cliAddr;
// Create socket
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0){
cout<<"errorOpeningSocket";
return 0;
}
bzero( (char*)&servAddr , sizeof(servAddr) );
portno=20009;
// Add the server address and port servAddr
servAddr.sin_family=AF_INET;
servAddr.sin_port=htons(portno);
//bind to server address
if( bind( sockfd,(struct sockaddr*) &servAddr, sizeof(servAddr) ) <0 ){
cout<<"ErrorOnbinding";
return 0;
}
// Listen for incoming connections (5 at a time)
listen(sockfd,5);
// If connected create a new socket out of clientlength
clilen=sizeof(cliAddr);
newsockfd=accept( sockfd, (struct sockaddr*) &cliAddr, &clilen );
if(newsockfd<0){
cout<<"ErrorOnAccept!";
return 0;
}
// Keep receiveing and sending messages
while(1){
bzero(buffer,256);
n=read(newsockfd,buffer,255);
if(n<0){
cout<<"ErrorReadingFromSocket!";
return 0;
}
cout<<"Message: "<<buffer<<endl;
cin>>buffer;
n=write(newsockfd,buffer,strlen(buffer));
}
return 0;
}
#include<stdio.h>
#include<iostream>
#include<unistd.h>
// For vfs shit
#include<sys/statvfs.h>
using namespace std;
int main()
{
// A struct explained in pdf of osLab by vinod
struct statvfs data;
// Give valid path
char path[128]="/home/us/s13/s1338/s7/6-vfs";
// get stats of file system
int ret=statvfs(path,&data);
if(ret==-1)
return -1;
// Print some shit from those stats
cout<<"free blocks : "<<data.f_blocks<<endl;
cout<<"b free : "<<data.f_bfree<<endl;
cout<<"free size : "<<data.f_frsize<<endl;
return 0;
}
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#define max 20
using namespace std;
void print(vector<int> a)
{
auto i=a.begin();
auto k=a.end();
//cout<<"\n";
for(;i!=k;++i)
{
cout<<*i<<" ";
}
cout<<"\n";
}
class matrix
{
public:
int r;
int c;
int m[max][max];
void read()
{
//cout<<"dim : ";
cin>>r>>c;
for(int i=0;i<r;++i)
for(int j=0;j<c;++j)
cin>>m[i][j];
}
matrix operator -(matrix b)
{
matrix d;
d.r=r;
d.c=c;
for(int i=0;i<r;++i)
for(int j=0;j<c;++j)
d.m[i][j]=m[i][j]-b.m[i][j];
return d;
}
void print()
{
for(int i=0;i<r;++i)
{
for(int j=0;j<c;++j)
cout<<m[i][j]<<" ";
cout<<"\n";
}
}
int find(vector<int> row, vector<bool> finish)
{
for(int i=0;i<r;++i)
{
int f=1;
for(int j=0;j<c;++j)
{
if(m[i][j]>row[j])
f=0;
}
if(f && !finish[i]){
cout<<i<<"th row : ";
::print(getRow(i));
::print(row);
return i;
}
}
return -1;
}
void chrow(int row, vector<int> nrow)
{
for(int j=0;j<c;++j)
m[row][j]=nrow[j];
}
vector<int> getRow(int row)
{
vector<int> a;
for(int j=0;j<c;++j)
a.push_back(m[row][j]);
return a;
}
};
vector<int> minusv(vector<int> a, vector<int> b)
{
auto i=a.begin();
auto j=b.begin();
auto k=a.end();
auto l=b.end();
vector<int> res;
for(;i!=k&&j!=l;++i,++j)
{
res.push_back(*i-*j);
}
return res;
}
vector<int> plusv(vector<int> a, vector<int> b)
{
auto i=a.begin();
auto j=b.begin();
auto k=a.end();
auto l=b.end();
vector<int> res;
for(;i!=k&&j!=l;++i,++j)
{
res.push_back(*i+*j);
}
return res;
}
vector<int> read()
{
vector<int> temp;
int n;
cin>>n;
for(int i=0;i<n;++i){
int t;
cin>>t;
temp.push_back(t);
}
return temp;
}
class bankers
{
public:
int r,c;
matrix allocated, total, need;
vector<int> avail;
bool request(int row, vector<int> req)
{
for(int i=0;i<c;++i){
if(req[i]>need.m[row][i])
{
cout<<"Request greater than need";
return false;
}
if(req[i]>avail[i])
{
cout<<"Request greater than available";
return false;
}
}
cout<<"\n Allocating resources to process "<<row<<" : ";
print(req);
avail = minusv(avail, req);
allocated.chrow(row,plusv(allocated.getRow(row),req));
need.chrow(row,minusv(need.getRow(row),req));
auto temp = safety();
if(!temp.first)
{
cout<<"\n Allocation is unsafe, rolling back changes";
avail = plusv(avail, req);
allocated.chrow(row,minusv(allocated.getRow(row),req));
need.chrow(row,plusv(need.getRow(row),req));
}
else
{
cout<<" new Safe sequence : ";
print(temp.second);
}
}
pair<bool,vector<int> > safety()
{
vector<int> work= avail;
vector<bool> finish;
for(int i=0;i<r;++i)
finish.push_back(false);
vector<int> safeSequence;
while(find(finish.begin(),finish.end(),false)!=finish.end()){
int row=need.find(work,finish);
if(row==-1){
auto temp=*new pair<bool,vector<int> >;
temp.first=false;
temp.second=*new vector<int>;
return temp;
}
else
{
for(int j=0;j<c;++j)
{
work[j]+=allocated.m[row][j];
}
finish[row]=true;
safeSequence.push_back(row);
}
}
auto temp=*new pair<bool,vector<int> >;
temp.first=true;
temp.second=safeSequence;
return temp;
}
bankers(matrix allocated, matrix total,vector<int> avail)
{
this->r=allocated.r;
this->c=allocated.c;
this->allocated = allocated;
this->total = total;
this->avail = avail;
this->need = this->total - this->allocated;
auto safe = safety();
if(!safe.first)
cout<<"Initial State is not safe\n";
else
{
cout<<"\nSafe sequence is : ";
print(safe.second);
}
}
void describe()
{
cout<<endl;
cout<<"Allocated"<<endl;
allocated.print();
cout<<endl<<"Total"<<endl;
total.print();
cout<<endl<<"Need"<<endl;
need.print();
cout<<endl<<"Available"<<endl;
print(avail);
}
};
int main()
{
freopen("input","r",stdin);
matrix al, tot;
al.read();
tot.read();
vector<int> res=read();
bankers b(al,tot,res);
b.describe();
int process;
cin>>process;
vector<int> req=read();
b.request(process,req);
cout<<"After state";
b.describe();
return 0;
}
/*
INPUT
5 3
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
5 3
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
3
3 3 2
0
3
3 3 2
OUTPUT
1th row : 1 2 2
3 3 2
3th row : 0 1 1
5 3 2
0th row : 7 4 3
7 4 3
2th row : 6 0 0
7 5 3
4th row : 4 3 1
10 5 5
Safe sequence is : 1 3 0 2 4
Allocated
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
Total
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
Need
7 4 3
1 2 2
6 0 0
0 1 1
4 3 1
Available
3 3 2
Allocating resources to process 0 : 3 3 2
Allocation is unsafe, rolling back changesAfter state
Allocated
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
Total
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
Need
7 4 3
1 2 2
6 0 0
0 1 1
4 3 1
Available
3 3 2
*/
/*For compiling shit with threads in it, use -lpthread tag in g++*/
#include<iostream>
/*Gonna use semaphores*/
#include<semaphore.h>
/*Gonna use multithreading, each philosopher being a thread*/
#include<pthread.h>
/*For thread control, not used currently*/
#include<fcntl.h>
/*As always rest of the party*/
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<string>
#define max 6
using namespace std;
/*Five semaphores for each of the chopsticks and a mutex for ensuring at least one philosopher eats*/
sem_t chopstick[max],mutex;
/*A thread for each of the philosophers*/
pthread_t philosopher[max];
/*Eat will be the function called by the threads, the philosopher thinks, eats if available, and then thinks*/
/*Another variation possible is it randomly thinks and randomly eats in an infinite loop*/
void *eat(void *args)
{
/*Number of chopsticks*/
int *num = (int*) args;
int n = *num;
/*First wait*/
cout<<"Waiting : " + to_string(n) + "\n";
/*Try to get, i and i+1 mod 5 chopstick*/
/*Sem wait is the same as wait() function of semaphore*/
sem_wait(&chopstick[n]);
sem_wait(&chopstick[(n+1)%max]);
/*To ensure that deadlock does not occur at most max-1 philosophers will be able to go into eat state at the same time*/
sem_wait(&mutex);
/*After eating, release all semaphore and go to think state*/
cout<<"Eating : " + to_string(n) + "\n";
sem_post(&mutex);
sem_post(&chopstick[(n+1)%max]);
sem_post(&chopstick[n]);
cout<<"Thinking : " + to_string(n) + "\n";
}
using namespace std;
int main()
{
/*Try initialising all chopsticks as one*/
for(int i=0;i<max;++i)
{
if(sem_init(&chopstick[i],0,1)==-1)
{
cout<<"Error init";
return -1;
}
}
/*init mutex as max-1*/
if(sem_init(&mutex,0,max-1)==-1)
{
cout<<"Error init";
return -1;
}
/*Create an array to track indices (just passing i, had issues)*/
/*If i sent i, in 0th iteration, the loop might have gone on and changed value of i, so basically i is stored somewhere else where it won't change*/
int n[max];
/*store i*/
for (int i=0;i<max;++i)
n[i]=i;
/*Create max number of threads for each philosopher, on create call the eat method*/
for(int i=0;i<max;++i)
{
pthread_create(&philosopher[i],NULL,&eat,&n[i]);
}
/*After all threads complete, exit the program*/
pthread_exit(NULL);
return 0;
}
/*Thread racing program, create n threads, make then increase by random numbers, when one gets its count to hundred, declare that thread to be the winner*/
#include<iostream>
#include<sys/types.h>
#include<unistd.h>
/*Uses threads, so pthread library*/
#include<pthread.h>
#include<stdlib.h>
using namespace std;
/*To know if at least one has crossed hundred, if it has don't print anymore*/
bool over;
void *worker(void *args)
{
/*Get the thread id from argument*/
int *tid = (int*)args;
/*Start with 0*/
int num=0;
/*While all threads are still racing and I'm not yet at 100*/
while(!over && num<=100)
{
/*Take a random step*/
int inc = rand()%10+1;
num+=inc;
/*Did i win?*/
if(num>100){
/*If I win, declare the contest to have ended, and proclaim me as the winner*/
over=true;
printf("%d : %d\n",*tid,num);
cout<<" Winner : "<<*tid<<endl;
}
/*Only print the number if someone hasn't won yet*/
if(!over)
printf("%d : %d\n",*tid,num);
sleep(1);
}
}
int main()
{
/*Create seven runners*/
pthread_t a[7];
/*Make id's for then (i changing issue as seen in dining philosopher)*/
int id[7]={0,1,2,3,4,5,6};
/*init over*/
over=false;
/*On you marks, get set, GO*/
for(int i=0;i<7;++i)
{
pthread_create(&a[i],NULL,&worker,&id[i]);
}
/*Wait for the last guy*/
pthread_exit(NULL);
/*Kill them all, Show no mercy*/
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment