2008年11月30日 星期日
Knight's Tour using recursive programing
/* 若是用遞迴,對於棋盤格數較多則時間會花很久 ( 注意並非無限迴圈 ) */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define col_size 5
#define row_size 5
void clear();
int knight(int,int);
int checker[row_size+4][col_size+4];
int step=0;
int ans=0;
// Knight's directions in X-axis and Y-axis.
const int horizontal[8]={ 2, 1,-1,-2,-2,-1, 1, 2};
const int vertical[8]={-1,-2,-2,-1, 1, 2, 2, 1};
int main()
{
time_t ticks1,ticks2;
int i,j,p,t;
clear();
ticks1 = time(NULL);
for(p=2;p<row_size+2;p++)
for(t=2;t<col_size+2;t++)
if(knight(p,t)==row_size*col_size)
{
printf("\nAns : %d\tStep : %d\n",++ans,step);
for(i=2;i<row_size+2;i++)
{
for(j=2;j<col_size+2;j++)
printf("%3d",checker[i][j]);
printf("\n");
}
clear();
}
ticks2 = time(NULL);
printf("\nStart time : %.24s\r\n",ctime(&ticks1));
printf(" End time : %.24s\r\n",ctime(&ticks2));
system("PAUSE");
return 0;
}
// To avoid that the knight goes out of range.
void clear()
{
int i,j;
for(i=0;i<row_size+4;i++)
for(j=0;j<col_size+4;j++)
if(i<2||i>row_size+1||j<2||j>col_size+1)
checker[i][j]=-1;
else
checker[i][j]=0;
step=0;
}
// Find the path.
int knight(int i,int j)
{
// Set the step right now.
checker[i][j]=++step;
int p;
// If the checker board is not full then find the next step.
if(step<row_size*col_size)
for(p=0;p<8;p++)
// Test the eight directions.
if(checker[i+vertical[p]][j+horizontal[p]]==0)
knight(i+vertical[p],j+horizontal[p]);
// If the checker board is full then return,
// otherwise clear the last step and restart from last step.
if(step==col_size*row_size)
return step;
--step;
checker[i][j]=0;
return step;
}
2008年11月29日 星期六
Minimum and Maximum
// Find the maximum and minimum. Using non-recursive programming.
// Input file:void
// Output:Stdout (show on monitor)
int Minimum(char A[],int size)
{
int min=A[0];
int i;
for(i=1;i>A[i];i++)
min=A[i];
return min;
}
int Maximum(char A[],int size)
{
int max=A[0];
int i;
for(i=1;i>A[i];i++)
max=A[i];
return max;
}
// Input file:void
// Output:Stdout (show on monitor)
int Minimum(char A[],int size)
{
int min=A[0];
int i;
for(i=1;i>A[i];i++)
min=A[i];
return min;
}
int Maximum(char A[],int size)
{
int max=A[0];
int i;
return max;
}
Randomized-Select to find the ith smallest element
// Find the ith smallest element of the array A[p..r]. Using non-recursive programming.
// Input file:void
// Output:Stdout (show on monitor)
int Randomized_Select(char A[],int p,int r,int i)
{
if(p==r)
return A[p];
int q=Randomized_Partition(A,p,r);
int k=q-p+1;
if(i==k) // the pivot is the answer
return A[q];
else if(ii-k);
}
// Using randomized method to find the KEY
int Randomized_Partition(char A[],int p,int r)
{
int i=rand()%(r-p+1)+p;
Swap(A,r,i);
return Partition(A,p,r);
}
// Comparision and divide (1.> KEY 2.<= KEY)
int Partition(char A[],int p,int r)
{
int x=A[r];
int i=p-1;
int j;
for(j=p;j<=r-1;j++)
if(A[j]<=x)
Swap(A,++i,j);
Swap(A,i+1,r);
return i+1;
}
// Exchange two elements of the data
void Swap(char A[],int i,int j)
{
int temp=A[i];
A[i]=A[j];
A[j]=temp;
return;
}
// Input file:void
// Output:Stdout (show on monitor)
int Randomized_Select(char A[],int p,int r,int i)
{
if(p==r)
return A[p];
int q=Randomized_Partition(A,p,r);
int k=q-p+1;
if(i==k) // the pivot is the answer
return A[q];
else if(i
}
// Using randomized method to find the KEY
int Randomized_Partition(char A[],int p,int r)
{
int i=rand()%(r-p+1)+p;
Swap(A,r,i);
return Partition(A,p,r);
}
// Comparision and divide (1.> KEY 2.<= KEY)
int Partition(char A[],int p,int r)
{
int x=A[r];
int i=p-1;
int j;
for(j=p;j<=r-1;j++)
if(A[j]<=x)
Swap(A,++i,j);
Swap(A,i+1,r);
return i+1;
}
// Exchange two elements of the data
void Swap(char A[],int i,int j)
{
int temp=A[i];
A[i]=A[j];
A[j]=temp;
return;
}
Midterm ex6
Please add a signal handler to the above server so that there won't be any zombie process.
/* 修改 ex5 部分用藍色表示 */
//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
struct ans
{
int answer;
};
void guess(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
struct ans ans;
printf("Please guess a number between 1 and 100:\n");
do {
if (Fgets(sendline, MAXLINE, fp) != NULL) {
if (sscanf(sendline, "%d", &ans.answer)!=1)
printf("Invalid input: %s", sendline);
else if (ans.answer>100 || ans.answer<1) sockfd =" Socket(AF_INET," sin_family =" AF_INET;" sin_port =" htons(SERV_PORT);" style="color: rgb(0, 153, 0);">/* do it all */
exit(0);
}
//-------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------- //tcpserv01.c
#include "unp.h"
struct ans
{
int answer;
};
void sig_chld(int signo)
{
pid_t pid;
int stat;
while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated\n", pid);
return;
}
void retrt(int sockfd)
{
char buf[MAXLINE];
ssize_t n;
struct ans ans;
int result;
srand(time(NULL));
result=rand()%100+1;
printf("The answer is %d\n",result);
do {
if ( (n = Readn(sockfd, &ans, sizeof(ans))) == 0)
return; /* connection closed by other end */
if (ans.answer>result) strcpy(buf,"Guess a smaller number!\n");
else if (ans.answer
else strcpy(buf,"You got the answer!\n");
Writen(sockfd, buf, strlen(buf));
} while (strcmp(buf,"You got the answer!\n")!=0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
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(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
Signal(SIGCHLD, sig_chld);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
retrt(connfd); /* process the request */
exit(0);
}
Close(connfd); /* parent closes connected socket */
}
}
//-------------------------------------------------------------------------------------------
/* 修改 ex5 部分用藍色表示 */
//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
struct ans
{
int answer;
};
void guess(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
struct ans ans;
printf("Please guess a number between 1 and 100:\n");
do {
if (Fgets(sendline, MAXLINE, fp) != NULL) {
if (sscanf(sendline, "%d", &ans.answer)!=1)
printf("Invalid input: %s", sendline);
else if (ans.answer>100 || ans.answer<1) sockfd =" Socket(AF_INET," sin_family =" AF_INET;" sin_port =" htons(SERV_PORT);" style="color: rgb(0, 153, 0);">/* do it all */
exit(0);
}
//-------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------- //tcpserv01.c
#include "unp.h"
struct ans
{
int answer;
};
void sig_chld(int signo)
{
pid_t pid;
int stat;
while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated\n", pid);
return;
}
void retrt(int sockfd)
{
char buf[MAXLINE];
ssize_t n;
struct ans ans;
int result;
srand(time(NULL));
result=rand()%100+1;
printf("The answer is %d\n",result);
do {
if ( (n = Readn(sockfd, &ans, sizeof(ans))) == 0)
return; /* connection closed by other end */
if (ans.answer>result) strcpy(buf,"Guess a smaller number!\n");
else if (ans.answer
}
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
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(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
Signal(SIGCHLD, sig_chld);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
retrt(connfd); /* process the request */
exit(0);
}
Close(connfd); /* parent closes connected socket */
}
}
//-------------------------------------------------------------------------------------------
Midterm ex5
Please revise the above program so that many clients can play the number-guessing game with the concurrent server.
/* 修改 ex4 部分用藍色表示 */
//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
struct ans
{
int answer;
};
void guess(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
struct ans ans;
printf("Please guess a number between 1 and 100:\n");
do {
if (Fgets(sendline, MAXLINE, fp) != NULL) {
if (sscanf(sendline, "%d", &ans.answer)!=1)
printf("Invalid input: %s", sendline);
else if (ans.answer>100 || ans.answer<1)>");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
guess(stdin, sockfd); /* do it all */
exit(0);
}
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
//tcpserv01.c
#include "unp.h"
struct ans
{
int answer;
};
void retrt(int sockfd)
{
char buf[MAXLINE];
ssize_t n;
struct ans ans;
int result;
srand(time(NULL));
result=rand()%100+1;
printf("The answer is %d\n",result);
do {
if ( (n = Readn(sockfd, &ans, sizeof(ans))) == 0)
return; /* connection closed by other end */
if (ans.answer>result) strcpy(buf,"Guess a smaller number!\n");
else if (ans.answer
else strcpy(buf,"You got the answer!\n");
Writen(sockfd, buf, strlen(buf));
} while (strcmp(buf,"You got the answer!\n")!=0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
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(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
retrt(connfd); /* process the request */
exit(0);
}
Close(connfd); /* parent closes connected socket */
}
}
//-------------------------------------------------------------------------------------------
/* 修改 ex4 部分用藍色表示 */
//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
struct ans
{
int answer;
};
void guess(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
struct ans ans;
printf("Please guess a number between 1 and 100:\n");
do {
if (Fgets(sendline, MAXLINE, fp) != NULL) {
if (sscanf(sendline, "%d", &ans.answer)!=1)
printf("Invalid input: %s", sendline);
else if (ans.answer>100 || ans.answer<1)>");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
guess(stdin, sockfd); /* do it all */
exit(0);
}
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
//tcpserv01.c
#include "unp.h"
struct ans
{
int answer;
};
void retrt(int sockfd)
{
char buf[MAXLINE];
ssize_t n;
struct ans ans;
int result;
srand(time(NULL));
result=rand()%100+1;
printf("The answer is %d\n",result);
do {
if ( (n = Readn(sockfd, &ans, sizeof(ans))) == 0)
return; /* connection closed by other end */
if (ans.answer>result) strcpy(buf,"Guess a smaller number!\n");
else if (ans.answer
else strcpy(buf,"You got the answer!\n");
Writen(sockfd, buf, strlen(buf));
} while (strcmp(buf,"You got the answer!\n")!=0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
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(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
retrt(connfd); /* process the request */
exit(0);
}
Close(connfd); /* parent closes connected socket */
}
}
//-------------------------------------------------------------------------------------------
Midterm ex4
Please design a number-guessing game, such that the client sends an integer to the server. After received the integer, the server compares the integer with its answer and sends a reply to the client. If the integer is greater than the answer, the server sends the string "Guess a smaller number!" to the client; if the integer is smaller than the answer, the server send the string "Guess a greater number!" to the client. Otherwise, the server sends the string "You got the answer!" to the client and the connection is closed. Note that, the answer is between 1 and 100, and it is randomly generated, the guessing-number is inputted from the keyboard.
//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
struct ans
{
int answer;
};
void guess(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
struct ans ans;
printf("Please guess a number between 1 and 100:\n");
do {
if (Fgets(sendline, MAXLINE, fp) != NULL) {
if (sscanf(sendline, "%d", &ans.answer)!=1)
printf("Invalid input: %s", sendline);
else if (ans.answer>100 || ans.answer<1)>");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
guess(stdin, sockfd); /* do it all */
exit(0);
}
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
//tcpserv01.c
#include "unp.h"
struct ans
{
int answer;
};
void retrt(int sockfd)
{
char buf[MAXLINE];
ssize_t n;
struct ans ans;
int result;
srand(time(NULL));
result=rand()%100+1;
printf("The answer is %d\n",result);
do {
if ( (n = Readn(sockfd, &ans, sizeof(ans))) == 0)
return; /* connection closed by other end */
if (ans.answer>result) strcpy(buf,"Guess a smaller number!\n");
else if (ans.answer
else strcpy(buf,"You got the answer!\n");
Writen(sockfd, buf, strlen(buf));
} while (strcmp(buf,"You got the answer!\n")!=0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
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(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
retrt(connfd); /* process the request */
Close(connfd); /* parent closes connected socket */
}
}
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
struct ans
{
int answer;
};
void guess(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
struct ans ans;
printf("Please guess a number between 1 and 100:\n");
do {
if (Fgets(sendline, MAXLINE, fp) != NULL) {
if (sscanf(sendline, "%d", &ans.answer)!=1)
printf("Invalid input: %s", sendline);
else if (ans.answer>100 || ans.answer<1)>");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
guess(stdin, sockfd); /* do it all */
exit(0);
}
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
//tcpserv01.c
#include "unp.h"
struct ans
{
int answer;
};
void retrt(int sockfd)
{
char buf[MAXLINE];
ssize_t n;
struct ans ans;
int result;
srand(time(NULL));
result=rand()%100+1;
printf("The answer is %d\n",result);
do {
if ( (n = Readn(sockfd, &ans, sizeof(ans))) == 0)
return; /* connection closed by other end */
if (ans.answer>result) strcpy(buf,"Guess a smaller number!\n");
else if (ans.answer
else strcpy(buf,"You got the answer!\n");
Writen(sockfd, buf, strlen(buf));
} while (strcmp(buf,"You got the answer!\n")!=0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
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(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
retrt(connfd); /* process the request */
Close(connfd); /* parent closes connected socket */
}
}
//-------------------------------------------------------------------------------------------
Midterm ex3
Please revise the above program so that the server will convert the IP address of the client and the server to numbers. Note that, the numbers should be shown on the console of the server. (Remember to check the correctness of the numbers.)
/* 修改 ex2 的部分用藍色顯示,位指轉數字要用ntohl() 轉才不會有 byte order 的問題 ( 即 a*128^3+b*128^2+c*128^1+d*128^0 變成 a*128^0+b*128^2+c*128^2+d*128^3 )*/
//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
void inexp(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
do {
printf("Please enter an expression (e.g. 123+456):\n");
if (Fgets(sendline, MAXLINE, fp) != NULL) {
Writen(sockfd, sendline, strlen(sendline));
if (Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("inexp: server terminated prematurely");
Fputs(recvline, stdout);
}
} while (strlen(recvline)>10);
}
int main(int argc, char **argv)
{
int sockfd, port;
struct sockaddr_in servaddr;
if (argc != 3)
err_quit("usage: tcpcli ");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
if (sscanf(argv[2],"%d", &port)==1)
servaddr.sin_port = htons(port);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
inexp(stdin, sockfd); /* do it all */
exit(0);
}
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
//tcpserv01.c
#include "unp.h"
void retrt(int sockfd)
{
char buf[MAXLINE], rep[MAXLINE], op;
int a, b;
int success=0;
do
{
a=b=0;
if (read(sockfd, buf, MAXLINE)>0)
{
printf("Received expression: %s\n",buf);
if (sscanf(buf, "%d%c%d",&a, &op, &b)!=3)
snprintf(rep, sizeof(rep), "Invalid input: %s\n", buf);
else if (a>=100 && a<=999 && b>=100 && b<=999)
{
switch(op)
{
case '+': snprintf(rep, sizeof(rep), "%d\n", a+b); success=1;
break;
case '-': snprintf(rep, sizeof(rep), "%d\n", a-b); success=1;
break;
case '*': snprintf(rep, sizeof(rep), "%d\n", a*b); success=1;
break;
case '/': snprintf(rep, sizeof(rep), "%d\n", a/b); success=1;
break;
case '%': snprintf(rep, sizeof(rep), "%d\n", a%b); success=1;
break;
default: snprintf(rep, sizeof(rep), "Invalid operator: %c\n", op);
}
}
else
snprintf(rep, sizeof(rep), "Invalid number: %d or %d\n", a, b);
Writen(sockfd, rep, strlen(rep));
}
} while(success==0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen, addrlen;
struct sockaddr_in cliaddr, servaddr, localaddr, peeraddr;
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(0);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);
bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);
if (getsockname(listenfd, (SA *) &localaddr, &addrlen)==0)
{
printf("Server's IP address: %s\n", inet_ntoa(localaddr.sin_addr));
printf("Server's port number: %d\n\n", ntohs(localaddr.sin_port));
}
Listen(listenfd, LISTENQ);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) NULL, NULL);
bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);
if (getsockname(connfd, (SA *) &localaddr, &addrlen)==0)
{
printf("Server's IP address: %s\n", inet_ntoa(localaddr.sin_addr));
printf("Server's port number: %d\n\n", ntohs(localaddr.sin_port));
printf("Server's IP number: %d\n\n", ntohl(localaddr.sin_addr.s_addr));
}
bzero(&peeraddr, sizeof(peeraddr));
addrlen = sizeof(peeraddr);
if (getpeername(connfd, (SA *) &peeraddr, &addrlen)==0)
{
printf("Client's IP address: %s\n", inet_ntoa(peeraddr.sin_addr));
printf("Client's port number: %d\n\n", ntohs(peeraddr.sin_port));
printf("Server's IP number: %d\n\n", ntohl(localaddr.sin_addr.s_addr));
}
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
retrt(connfd); /* process the request */
exit(0);
}
Close(connfd);
}
}
//-------------------------------------------------------------------------------------------
/* 修改 ex2 的部分用藍色顯示,位指轉數字要用ntohl() 轉才不會有 byte order 的問題 ( 即 a*128^3+b*128^2+c*128^1+d*128^0 變成 a*128^0+b*128^2+c*128^2+d*128^3 )*/
//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
void inexp(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
do {
printf("Please enter an expression (e.g. 123+456):\n");
if (Fgets(sendline, MAXLINE, fp) != NULL) {
Writen(sockfd, sendline, strlen(sendline));
if (Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("inexp: server terminated prematurely");
Fputs(recvline, stdout);
}
} while (strlen(recvline)>10);
}
int main(int argc, char **argv)
{
int sockfd, port;
struct sockaddr_in servaddr;
if (argc != 3)
err_quit("usage: tcpcli
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
if (sscanf(argv[2],"%d", &port)==1)
servaddr.sin_port = htons(port);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
inexp(stdin, sockfd); /* do it all */
exit(0);
}
//-------------------------------------------------------------------------------------------
#include "unp.h"
void retrt(int sockfd)
{
char buf[MAXLINE], rep[MAXLINE], op;
int a, b;
int success=0;
do
{
a=b=0;
if (read(sockfd, buf, MAXLINE)>0)
{
printf("Received expression: %s\n",buf);
if (sscanf(buf, "%d%c%d",&a, &op, &b)!=3)
snprintf(rep, sizeof(rep), "Invalid input: %s\n", buf);
else if (a>=100 && a<=999 && b>=100 && b<=999)
{
switch(op)
{
case '+': snprintf(rep, sizeof(rep), "%d\n", a+b); success=1;
break;
case '-': snprintf(rep, sizeof(rep), "%d\n", a-b); success=1;
break;
case '*': snprintf(rep, sizeof(rep), "%d\n", a*b); success=1;
break;
case '/': snprintf(rep, sizeof(rep), "%d\n", a/b); success=1;
break;
case '%': snprintf(rep, sizeof(rep), "%d\n", a%b); success=1;
break;
default: snprintf(rep, sizeof(rep), "Invalid operator: %c\n", op);
}
}
else
snprintf(rep, sizeof(rep), "Invalid number: %d or %d\n", a, b);
Writen(sockfd, rep, strlen(rep));
}
} while(success==0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen, addrlen;
struct sockaddr_in cliaddr, servaddr, localaddr, peeraddr;
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(0);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);
bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);
if (getsockname(listenfd, (SA *) &localaddr, &addrlen)==0)
{
printf("Server's IP address: %s\n", inet_ntoa(localaddr.sin_addr));
printf("Server's port number: %d\n\n", ntohs(localaddr.sin_port));
}
Listen(listenfd, LISTENQ);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) NULL, NULL);
bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);
if (getsockname(connfd, (SA *) &localaddr, &addrlen)==0)
{
printf("Server's IP address: %s\n", inet_ntoa(localaddr.sin_addr));
printf("Server's port number: %d\n\n", ntohs(localaddr.sin_port));
printf("Server's IP number: %d\n\n", ntohl(localaddr.sin_addr.s_addr));
}
bzero(&peeraddr, sizeof(peeraddr));
addrlen = sizeof(peeraddr);
if (getpeername(connfd, (SA *) &peeraddr, &addrlen)==0)
{
printf("Client's IP address: %s\n", inet_ntoa(peeraddr.sin_addr));
printf("Client's port number: %d\n\n", ntohs(peeraddr.sin_port));
printf("Server's IP number: %d\n\n", ntohl(localaddr.sin_addr.s_addr));
}
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
retrt(connfd); /* process the request */
exit(0);
}
Close(connfd);
}
}
Midterm ex2
Please revise the above simple calculator so that the server won't bind a specific IP address and port to its sockets and it will show the IP address and port number of both the client and the server after the connection between the client and the server has been established.
/* Port 要用 ntohs() 去轉,否則會有 byte order 的問題,
getsockname() 及 getpeername() 前要先 bezero() 結果才不會不正常。 */
//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
void inexp(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
do {
printf("Please enter an expression (e.g. 123+456):\n");
if (Fgets(sendline, MAXLINE, fp) != NULL) {
Writen(sockfd, sendline, strlen(sendline));
if (Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("inexp: server terminated prematurely");
Fputs(recvline, stdout);
}
} while (strlen(recvline)>10);
}
int main(int argc, char **argv)
{
int sockfd, port;
struct sockaddr_in servaddr;
if (argc != 3)
err_quit("usage: tcpcli ");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
if (sscanf(argv[2],"%d", &port)==1)
servaddr.sin_port = htons(port);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
inexp(stdin, sockfd); /* do it all */
exit(0);
}
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
//tcpserv01.c
#include "unp.h"
void retrt(int sockfd)
{
char buf[MAXLINE], rep[MAXLINE], op;
int a, b;
int success=0;
do
{
a=b=0;
if (read(sockfd, buf, MAXLINE)>0)
{
printf("Received expression: %s\n",buf);
if (sscanf(buf, "%d%c%d",&a, &op, &b)!=3)
snprintf(rep, sizeof(rep), "Invalid input: %s\n", buf);
else if (a>=100 && a<=999 && b>=100 && b<=999)
{
switch(op)
{
case '+': snprintf(rep, sizeof(rep), "%d\n", a+b); success=1;
break;
case '-': snprintf(rep, sizeof(rep), "%d\n", a-b); success=1;
break;
case '*': snprintf(rep, sizeof(rep), "%d\n", a*b); success=1;
break;
case '/': snprintf(rep, sizeof(rep), "%d\n", a/b); success=1;
break;
case '%': snprintf(rep, sizeof(rep), "%d\n", a%b); success=1;
break;
default: snprintf(rep, sizeof(rep), "Invalid operator: %c\n", op);
}
}
else
snprintf(rep, sizeof(rep), "Invalid number: %d or %d\n", a, b);
Writen(sockfd, rep, strlen(rep));
}
} while(success==0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen, addrlen;
struct sockaddr_in cliaddr, servaddr, localaddr, peeraddr;
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(0);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);
if (getsockname(listenfd, (SA *) &localaddr, &addrlen)==0)
{
printf("Server's IP address: %s\n", inet_ntoa(localaddr.sin_addr));
printf("Server's port number: %d\n\n", ntohs(localaddr.sin_port));
}
Listen(listenfd, LISTENQ);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) NULL, NULL);
bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);
if (getsockname(connfd, (SA *) &localaddr, &addrlen)==0)
{
printf("Server's IP address: %s\n", inet_ntoa(localaddr.sin_addr));
printf("Server's port number: %d\n\n", ntohs(localaddr.sin_port));
}
bzero(&peeraddr, sizeof(peeraddr));
addrlen = sizeof(peeraddr);
if (getpeername(connfd, (SA *) &peeraddr, &addrlen)==0)
{
printf("Client's IP address: %s\n", inet_ntoa(peeraddr.sin_addr));
printf("Client's port number: %d\n\n", ntohs(peeraddr.sin_port));
}
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
retrt(connfd); /* process the request */
exit(0);
}
Close(connfd);
}
}
//-------------------------------------------------------------------------------------------
/* Port 要用 ntohs() 去轉,否則會有 byte order 的問題,
getsockname() 及 getpeername() 前要先 bezero() 結果才不會不正常。 */
//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
void inexp(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
do {
printf("Please enter an expression (e.g. 123+456):\n");
if (Fgets(sendline, MAXLINE, fp) != NULL) {
Writen(sockfd, sendline, strlen(sendline));
if (Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("inexp: server terminated prematurely");
Fputs(recvline, stdout);
}
} while (strlen(recvline)>10);
}
int main(int argc, char **argv)
{
int sockfd, port;
struct sockaddr_in servaddr;
if (argc != 3)
err_quit("usage: tcpcli
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
if (sscanf(argv[2],"%d", &port)==1)
servaddr.sin_port = htons(port);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
inexp(stdin, sockfd); /* do it all */
exit(0);
}
//-------------------------------------------------------------------------------------------
#include "unp.h"
void retrt(int sockfd)
{
char buf[MAXLINE], rep[MAXLINE], op;
int a, b;
int success=0;
do
{
a=b=0;
if (read(sockfd, buf, MAXLINE)>0)
{
printf("Received expression: %s\n",buf);
if (sscanf(buf, "%d%c%d",&a, &op, &b)!=3)
snprintf(rep, sizeof(rep), "Invalid input: %s\n", buf);
else if (a>=100 && a<=999 && b>=100 && b<=999)
{
switch(op)
{
case '+': snprintf(rep, sizeof(rep), "%d\n", a+b); success=1;
break;
case '-': snprintf(rep, sizeof(rep), "%d\n", a-b); success=1;
break;
case '*': snprintf(rep, sizeof(rep), "%d\n", a*b); success=1;
break;
case '/': snprintf(rep, sizeof(rep), "%d\n", a/b); success=1;
break;
case '%': snprintf(rep, sizeof(rep), "%d\n", a%b); success=1;
break;
default: snprintf(rep, sizeof(rep), "Invalid operator: %c\n", op);
}
}
else
snprintf(rep, sizeof(rep), "Invalid number: %d or %d\n", a, b);
Writen(sockfd, rep, strlen(rep));
}
} while(success==0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen, addrlen;
struct sockaddr_in cliaddr, servaddr, localaddr, peeraddr;
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(0);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);
if (getsockname(listenfd, (SA *) &localaddr, &addrlen)==0)
{
printf("Server's IP address: %s\n", inet_ntoa(localaddr.sin_addr));
printf("Server's port number: %d\n\n", ntohs(localaddr.sin_port));
}
Listen(listenfd, LISTENQ);
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) NULL, NULL);
bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);
if (getsockname(connfd, (SA *) &localaddr, &addrlen)==0)
{
printf("Server's IP address: %s\n", inet_ntoa(localaddr.sin_addr));
printf("Server's port number: %d\n\n", ntohs(localaddr.sin_port));
}
bzero(&peeraddr, sizeof(peeraddr));
addrlen = sizeof(peeraddr);
if (getpeername(connfd, (SA *) &peeraddr, &addrlen)==0)
{
printf("Client's IP address: %s\n", inet_ntoa(peeraddr.sin_addr));
printf("Client's port number: %d\n\n", ntohs(peeraddr.sin_port));
}
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
retrt(connfd); /* process the request */
exit(0);
}
Close(connfd);
}
}
Midterm ex1
Please a design a simple calculator client and server such that the client sends an expression (e.g."123+456), which contains two operands and an operator, to the server. After received the expression, the server replies the caculating result to the client. Note that, the operands are 3-digit integer, the operator is in {+,-,*,/,%}, the expression is inputted from the keyboard, and the caculating result should be shown on the console of the client.
//---------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
void inexp(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
do {
printf("Please enter an expression (e.g. 123+456):\n");
if (Fgets(sendline, MAXLINE, fp) != NULL) {
Writen(sockfd, sendline, strlen(sendline));
if (Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("inexp: server terminated prematurely");
Fputs(recvline, stdout);
}
} while (strlen(recvline)>10);
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
err_quit("usage: tcpcli");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
inexp(stdin, sockfd); /* do it all */
exit(0);
}
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
//tcpserv01.c
#include "unp.h"
void retrt(int sockfd)
{
char buf[MAXLINE], rep[MAXLINE], op;
int a, b;
int success=0;
do
{
a=b=0;
if (read(sockfd, buf, MAXLINE)>0)
{
printf("Received expression: %s\n",buf);
if (sscanf(buf, "%d%c%d",&a, &op, &b)!=3)
snprintf(rep, sizeof(rep), "Invalid input: %s\n", buf);
else if (a>=100 && a<=999 && b>=100 && b<=999)
{
switch(op)
{
case '+': snprintf(rep, sizeof(rep), "%d\n", a+b); success=1;
break;
case '-': snprintf(rep, sizeof(rep), "%d\n", a-b); success=1;
break;
case '*': snprintf(rep, sizeof(rep), "%d\n", a*b); success=1;
break;
case '/': snprintf(rep, sizeof(rep), "%d\n", a/b); success=1;
break;
case '%': snprintf(rep, sizeof(rep), "%d\n", a%b); success=1;
break;
default: snprintf(rep, sizeof(rep), "Invalid operator: %c\n", op);
}
}
else snprintf(rep, sizeof(rep), "Invalid number: %d or %d\n", a, b);
Writen(sockfd, rep, strlen(rep));
}
} while(success==0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
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(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; ) {
connfd = Accept(listenfd, (SA *) NULL, NULL);
retrt(connfd); /* process the request */
Close(connfd);
}
}
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"
void inexp(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
do {
printf("Please enter an expression (e.g. 123+456):\n");
if (Fgets(sendline, MAXLINE, fp) != NULL) {
Writen(sockfd, sendline, strlen(sendline));
if (Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("inexp: server terminated prematurely");
Fputs(recvline, stdout);
}
} while (strlen(recvline)>10);
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
err_quit("usage: tcpcli
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
inexp(stdin, sockfd); /* do it all */
exit(0);
}
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
//tcpserv01.c
#include "unp.h"
void retrt(int sockfd)
{
char buf[MAXLINE], rep[MAXLINE], op;
int a, b;
int success=0;
do
{
a=b=0;
if (read(sockfd, buf, MAXLINE)>0)
{
printf("Received expression: %s\n",buf);
if (sscanf(buf, "%d%c%d",&a, &op, &b)!=3)
snprintf(rep, sizeof(rep), "Invalid input: %s\n", buf);
else if (a>=100 && a<=999 && b>=100 && b<=999)
{
switch(op)
{
case '+': snprintf(rep, sizeof(rep), "%d\n", a+b); success=1;
break;
case '-': snprintf(rep, sizeof(rep), "%d\n", a-b); success=1;
break;
case '*': snprintf(rep, sizeof(rep), "%d\n", a*b); success=1;
break;
case '/': snprintf(rep, sizeof(rep), "%d\n", a/b); success=1;
break;
case '%': snprintf(rep, sizeof(rep), "%d\n", a%b); success=1;
break;
default: snprintf(rep, sizeof(rep), "Invalid operator: %c\n", op);
}
}
else snprintf(rep, sizeof(rep), "Invalid number: %d or %d\n", a, b);
Writen(sockfd, rep, strlen(rep));
}
} while(success==0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
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(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; ) {
connfd = Accept(listenfd, (SA *) NULL, NULL);
retrt(connfd); /* process the request */
Close(connfd);
}
}
//---------------------------------------------------------------------------------------------
HW05
// Concurrent Servers and Clients
// Under Linux
// 範例為輸入兩個double回傳總合
// 課堂上修改為輸入三個double回傳總和以及平均(須有小數點)
// 沒更動的部分用原來顏色 , 修改部分用藍色
// 注意數字型態的傳遞很重要 , 不對就一定顯示不出來
//--------------------------------------------------------------------------
// tcpcli01.c
#include "unp.h"
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
err_quit("usage: tcpcli");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
str_cli(stdin, sockfd); /* do it all */
exit(0);
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// str_cli.c
#include "unp.h"
#include "sum.h"
void str_cli(FILE *fp, int sockfd)
{
char sendline[MAXLINE];
struct args args;
struct result result;
while (Fgets(sendline, MAXLINE, fp) != NULL) {
// Add the third argument
if (sscanf(sendline, "%ld%ld%ld", &args.arg1, &args.arg2,&args.arg3) != 3){
printf("invalid input: %s", sendline);
continue;
}
Writen(sockfd, &args, sizeof(args));
if (Readn(sockfd, &result, sizeof(result)) == 0)
err_quit("str_cli: server terminated prematurely");
printf("The sum is %ld\n", result.sum);
// Notice the data type
printf("The average is %lf\n", result.ave);
}
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// tcpserv01.c
#include "unp.h"
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
void sig_chld(int);
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(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
Signal(SIGCHLD, sig_chld);
for ( ; ; ) {
clilen = sizeof(cliaddr);
if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) <>
if (errno == EINTR)
continue; /* back to for() */
else
err_sys("accept error");
}
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
str_echo(connfd); /* process the request */
exit(0);
}
Close(connfd); /* parent closes connected socket */
}
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// str_echo.c
#include "unp.h"
#include "sum.h"
void str_echo(int sockfd)
{
ssize_t n;
struct args args;
struct result result;
for ( ; ; ) {
if ( (n = Readn(sockfd, &args, sizeof(args))) == 0)
return; /* connection closed by other end */
result.sum = args.arg1 + args.arg2 + args.arg3 ;
// Count the average
result.ave = (double)result.sum / 3 ;
Writen(sockfd, &result, sizeof(result));
}
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// sum.h
struct args {
long arg1;
long arg2;
long arg3;
};
struct result {
long sum;
// Notice the data type
double ave;
};
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Goal : 砍掉成為Zombie的子程序
// sigchldwaitpid.c
#include "unp.h"
void sig_chld(int signo)
{
pid_t pid;
int stat;
while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated\n", pid);
return;
}
//--------------------------------------------------------------------------
// Under Linux
// 範例為輸入兩個double回傳總合
// 課堂上修改為輸入三個double回傳總和以及平均(須有小數點)
// 沒更動的部分用原來顏色 , 修改部分用藍色
// 注意數字型態的傳遞很重要 , 不對就一定顯示不出來
//--------------------------------------------------------------------------
// tcpcli01.c
#include "unp.h"
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
err_quit("usage: tcpcli
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
str_cli(stdin, sockfd); /* do it all */
exit(0);
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// str_cli.c
#include "unp.h"
#include "sum.h"
void str_cli(FILE *fp, int sockfd)
{
char sendline[MAXLINE];
struct args args;
struct result result;
while (Fgets(sendline, MAXLINE, fp) != NULL) {
// Add the third argument
if (sscanf(sendline, "%ld%ld%ld", &args.arg1, &args.arg2,&args.arg3) != 3){
printf("invalid input: %s", sendline);
continue;
}
Writen(sockfd, &args, sizeof(args));
if (Readn(sockfd, &result, sizeof(result)) == 0)
err_quit("str_cli: server terminated prematurely");
printf("The sum is %ld\n", result.sum);
// Notice the data type
printf("The average is %lf\n", result.ave);
}
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// tcpserv01.c
#include "unp.h"
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
void sig_chld(int);
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(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
Signal(SIGCHLD, sig_chld);
clilen = sizeof(cliaddr);
if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) <>
if (errno == EINTR)
continue; /* back to for() */
else
err_sys("accept error");
}
if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /* close listening socket */
str_echo(connfd); /* process the request */
exit(0);
}
Close(connfd); /* parent closes connected socket */
}
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// str_echo.c
#include "unp.h"
#include "sum.h"
void str_echo(int sockfd)
{
ssize_t n;
struct args args;
struct result result;
for ( ; ; ) {
if ( (n = Readn(sockfd, &args, sizeof(args))) == 0)
return; /* connection closed by other end */
result.sum = args.arg1 + args.arg2 + args.arg3 ;
// Count the average
result.ave = (double)result.sum / 3 ;
Writen(sockfd, &result, sizeof(result));
}
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// sum.h
struct args {
long arg1;
long arg2;
long arg3;
};
struct result {
long sum;
// Notice the data type
double ave;
};
//--------------------------------------------------------------------------
// Goal : 砍掉成為Zombie的子程序
// sigchldwaitpid.c
#include "unp.h"
void sig_chld(int signo)
{
pid_t pid;
int stat;
while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated\n", pid);
return;
}
//--------------------------------------------------------------------------
HW08
/* Goal : Please design a simple calculator client and server, such that client sends an expression (e.g."123+456"), which contains two operands and an operator, to the server. After received the expression, the server replies the calculating result to the client. Note that, the operands are 3-digit integer, the operator is in {+,-,*,/,%}, the expression is inputted from the keyboard, and the calculating result should be shown on the console of the client. */
//---------------------------------------------------------------------------------------------
//Input : Stdin
//Output : Stdout
//Note : 使用 UDP 協定 , 修改部分用藍色表示
//---------------------------------------------------------------------------------------------
// dg_cli is in udpcli01.c
// dg_echo is in udpserv01.c
#include "unp.h"
void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE + 1];
socklen_t len;
struct sockaddr *preply_addr;
preply_addr=malloc(servlen);
while (Fgets(sendline, MAXLINE, fp) != NULL)
{
Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
len=servlen;
n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
printf("reply from %s (ignore)\n",Sock_ntop(preply_addr,len));
recvline[n] = 0; /* null terminate */
Fputs(recvline, stdout);
}
}
void dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
{
long arg1,arg3;
char arg2;
int n;
socklen_t len;
char mesg[MAXLINE];
for ( ; ; )
{
len = clilen;
n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
if(sscanf(mesg,"%ld%c%ld",&arg1,&arg2,&arg3)==3)
if(arg1<100||arg1>999||arg3<100||arg3>999)
snprintf(mesg,sizeof(mesg),"%s\n","invalid operand");
else
switch(arg2)
{
case '+':
snprintf(mesg,sizeof(mesg),"%ld\n",arg1+arg3);
break;
case '*':
snprintf(mesg,sizeof(mesg),"%ld\n",arg1*arg3);
break;
case '-':
snprintf(mesg,sizeof(mesg),"%ld\n",arg1-arg3);
break;
case '/':
snprintf(mesg,sizeof(mesg),"%ld\n",arg1/arg3);
break;
case '%':
snprintf(mesg,sizeof(mesg),"%ld\n",arg1%arg3);
break;
default:
snprintf(mesg,sizeof(mesg),"%s\n","invalid operantor");
break;
}
Sendto(sockfd, mesg, sizeof(mesg), 0, pcliaddr, len);
}
}
//---------------------------------------------------------------------------------------------
//Input : Stdin
//Output : Stdout
//Note : 使用 UDP 協定 , 修改部分用藍色表示
//---------------------------------------------------------------------------------------------
// dg_cli is in udpcli01.c
// dg_echo is in udpserv01.c
#include "unp.h"
void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE + 1];
socklen_t len;
struct sockaddr *preply_addr;
preply_addr=malloc(servlen);
while (Fgets(sendline, MAXLINE, fp) != NULL)
{
Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
len=servlen;
n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
printf("reply from %s (ignore)\n",Sock_ntop(preply_addr,len));
recvline[n] = 0; /* null terminate */
Fputs(recvline, stdout);
}
}
void dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
{
long arg1,arg3;
char arg2;
int n;
socklen_t len;
char mesg[MAXLINE];
for ( ; ; )
{
len = clilen;
n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
if(sscanf(mesg,"%ld%c%ld",&arg1,&arg2,&arg3)==3)
if(arg1<100||arg1>999||arg3<100||arg3>999)
snprintf(mesg,sizeof(mesg),"%s\n","invalid operand");
else
switch(arg2)
{
case '+':
snprintf(mesg,sizeof(mesg),"%ld\n",arg1+arg3);
break;
case '*':
snprintf(mesg,sizeof(mesg),"%ld\n",arg1*arg3);
break;
case '-':
snprintf(mesg,sizeof(mesg),"%ld\n",arg1-arg3);
break;
case '/':
snprintf(mesg,sizeof(mesg),"%ld\n",arg1/arg3);
break;
case '%':
snprintf(mesg,sizeof(mesg),"%ld\n",arg1%arg3);
break;
default:
snprintf(mesg,sizeof(mesg),"%s\n","invalid operantor");
break;
}
Sendto(sockfd, mesg, sizeof(mesg), 0, pcliaddr, len);
}
}
訂閱:
文章 (Atom)