當前位置:編程學習大全網 - 源碼下載 - Goahead源代碼分析pdf

Goahead源代碼分析pdf

客戶

/* FTP服務的客戶端。動作:

-連接到服務器並請求服務

-向服務器發送樂思的大小信息

-開始從服務器接收文件

-緊密連接

*/

# include & ltstdio.h & gt

# include & ltsys/types . h & gt;

# include & ltsys/socket . h & gt;

# include & ltnetinet/in . h & gt;

# include & ltarpa/inet . h & gt;

# include & lttime.h & gt

# include & lt錯誤號& gt

# define SERVER _ PORT _ ID 6081

#定義客戶端端口ID 6086

#定義服務器_主機_ ADDR " 128.119 . 40 . 186 "

/* gaia.cs.umass.edu */

#定義MAXSIZE 512

#定義確認2

#定義NACK 3

#定義請求文件100

#define命令不支持150

#定義命令支持160

#定義壞文件名200

#定義文件名OK 400

#定義開始轉移500

int readn(int sd,char *ptr,int size);

int writen(int sd,char *ptr,int size);

main(int argc,char *argv[])

{

int sockid,newsockid,I,getfile,ack,msg,msg_2,c,len

int no_writen,start_xfer,num_blks,num _ last _ blk

struct sockaddr_in my_addr,server _ addr

FILE * fp

char in _ buf[MAXSIZE];

如果(argc!= 2) {printf("錯誤:用法:sftp文件名\ n ");退出(0);}

no _ writen = 0;

num _ blks = 0;

num _ last _ blk = 0;

len = strlen(argv[1]);

printf("client:正在創建套接字\ n ");

if ((sockid = socket(AF_INET,SOCK_STREAM,0))& lt;0)

{ printf("client: socket錯誤:%d\n ",errno);退出(0);

}

printf("client:綁定我的本地套接字\ n ");

bzero((char *)& amp;my_addr,sizeof(my _ addr));

我的_地址. sin _家庭= AF _ INET

my _ addr . sin _ addr . s _ addr = htonl(in addr _ ANY);

my _ addr . sin _ PORT = htons(CLIENT _ PORT _ ID);

if (bind(sockid,(struct sockaddr *)& amp;my_addr,sizeof(my _ addr))& lt;0)

{printf("client: bind error :%d\n ",errno);退出(0);

}

printf("client:正在啟動連接\ n ");

bzero((char *)& amp;server_addr,sizeof(server _ addr));

server _ addr . sin _ family = AF _ INET;

SERVER _ addr . sin _ addr . s _ addr = inet _ addr(服務器_主機_ ADDR);

SERVER _ addr . sin _ PORT = htons(SERVER _ PORT _ ID);

if (connect(sockid,(struct sockaddr *)& amp;服務器地址,

sizeof(server _ addr))& lt;0)

{ printf(" client:connect error:% d \ n ",errno);退出(0);

}

/*壹旦我們到達這裏,我們就可以連接到服務器*/

/*告訴服務器我們想要獲取壹個文件*/

getfile = htons(request file);

printf("client:向ftp服務器發送命令請求\ n ");

if((writen(sockid,(char *)& amp;getfile,sizeof(getfile)))& lt;0)

{printf("client:寫錯誤:%d\n ",errno);退出(0);}

/*希望從服務器獲得許可*/

msg = 0;

if((readn(sockid,(char *)& amp;msg,sizeof(msg)))& lt;0)

{printf("client:讀取錯誤:%d\n ",errno);退出(0);}

msg = ntohs(msg);

if (msg==COMMANDNOTSUPPORTED) {

printf("客戶端:服務器拒絕命令。再見\ n”);

退出(0);

}

其他

printf("客戶端:服務器回復了%d,命令支持\n ",msg);

/*將文件名發送到服務器*/

printf("client:發送文件名\ n ");

if ((writen(sockid,argv[1],len))& lt;0)

{printf("client:寫錯誤:%d\n ",errno);退出(0);}

/*查看服務器是否回復文件名正常*/

msg _ 2 = 0;

if ((readn(sockid,(char *)& amp;msg_2,sizeof(msg _ 2)))& lt;0)

{printf("client:讀取錯誤:%d\n ",errno);退出(0);}

msg _ 2 = ntohs(msg _ 2);

if (msg_2 == BADFILENAME) {

printf("客戶端:服務器報告了錯誤的文件名。再見。\ n ");

退出(0);

}

其他

printf("客戶端:服務器回復了%d,文件名OK\n ",msg _ 2);

/*客戶端知道服務器能夠以讀取方式打開文件

模式,並要求繼續*/

/*客戶端現在以寫模式打開文件的副本並發送

服務器的GOAHEAD */

printf("client:發送開始傳輸命令\ n ");

start _ xfer = STARTTRANSFER

start _ xfer = htons(start _ xfer);

if ((writen(sockid,(char *)& amp;start_xfer,sizeof(start _ xfer)))& lt;0)

{printf("client:寫錯誤:%d\n ",errno);退出(0);

}

if ((fp = fopen(argv[1]," w))= = NULL)

{printf(" client:本地打開文件錯誤\ n ");退出(0);}

/*現在客戶端正在從服務器讀取關於有多少

大小為MAXSIZE的完整塊。它也接收號碼

最後壹個部分填充的塊中剩余的字節數,如果有的話*/

if((readn(sockid,(char *)& amp;num_blks,sizeof(num _ blks)))& lt;0)

{ printf(" client:n blocks上的讀取錯誤:%d\n ",errno);退出(0);}

num _ blks = ntohs(num _ blks);

printf("客戶端:服務器響應:文件中有%d個塊\n ",num _ blks);

ack = ACK

ack = htons(ack);

if((writen(sockid,(char *)& amp;ack,sizeof(ack)))& lt;0)

{printf("client: ack寫入錯誤:%d\n ",errno);退出(0);

}

if((readn(sockid,(char *)& amp;num_last_blk,sizeof(num _ last _ blk)))& lt;0)

{printf("client:讀取錯誤:%d on nbytes\n ",errno);退出(0);}

num _ last _ blk = ntohs(num _ last _ blk);

printf("客戶端:服務器響應:%d字節last blk\n ",num _ last _ blk);

if((writen(sockid,(char *)& amp;ack,sizeof(ack)))& lt;0)

{printf("client: ack寫入錯誤:%d\n ",errno);退出(0);

}

/*開始讀取服務器發送的塊*/

printf("client:開始獲取文件內容\ n ");

for(I = 0;我& ltnum _ blksi ++) {

if((readn(sockid,in_buf,MAXSIZE))& lt;0)

{printf("client:塊錯誤讀取:%d\n ",errno);退出(0);}

no_writen = fwrite(in_buf,sizeof(char),MAXSIZE,FP);

if(no _ writen = = 0){ printf(" client:文件寫入錯誤\ n ");退出(0);}

if (no_writen!= MAXSIZE)

{printf("client:文件寫入錯誤:no_writen較小\ n ");退出(0);}

/*發送該塊的ACK */

if((writen(sockid,(char *)& amp;ack,sizeof(ack)))& lt;0)

{printf("client: ack寫入錯誤:%d\n ",errno);退出(0);}

printf(" %d ... ",我);

}

/*如果有最後壹個部分填充的塊,讀取它*/

if(num _ last _ blk & gt;0) {

printf("%d\n ",num _ blks);

if((readn(sockid,in_buf,num _ last _ blk))& lt;0)

{printf("client:讀取的最後壹個塊錯誤:%d\n ",errno);退出(0);}

no_writen = fwrite(in_buf,sizeof(char),num_last_blk,FP);

if (no_writen == 0)

{printf("client:最後壹個塊文件寫入錯誤:%d\n ",errno);退出(0);}

if (no_writen!=編號最後壹個區塊)

{printf("client:文件寫入錯誤:no_writen小於2 \ n ");退出(0);}

if((writen(sockid,(char *)& amp;ack,sizeof(ack)))& lt;0)

{printf("client :ack寫入錯誤:%d\n ",errno);退出(0);}

}

else printf(" \ n ");

/*文件傳輸結束。客戶端在關閉所有文件後終止

和插座*/

fclose(FP);

printf("client:文件傳輸完成\ n ");

close(sockid);

}

/*因為內核中套接字的緩沖區限制可能是

達到時,讀取和寫入可能會返回正值

少於請求的數量。因此我們稱這兩個過程為

以處理此類緊急情況*/

int readn(int sd,char *ptr,int size)

{ int no_left,no _ read

no _ left = size

while(no _ left & gt;0)

{ no_read = read(sd,ptr,no _ left);

if(no _ read & lt;0)返回(no _ read);

if(no _ read = = 0)break;

no _ left-= no _ read;

ptr+= no _ read;

}

return(size-no _ left);

}

int writen(int sd,char *ptr,int size)

{ int no_left,no _ written

no _ left = size

while(no _ left & gt;0)

{ no_written = write(sd,ptr,no _ left);

if(no _ written & lt;=0)返回(no _ written);

no _ left-= no _ written;

ptr+= no _ written;

}

return(size-no _ left);

}

計算機網絡服務器

# include & ltstdio.h & gt

# include & ltsys/types . h & gt;

# include & ltsys/socket . h & gt;

# include & ltnetinet/in . h & gt;

# include & ltarpa/inet . h & gt;

# include & lttime.h & gt

# include & lt錯誤號& gt

#定義我的端口ID 6081

#定義最高限額256

#定義MAXSIZE 512

#定義確認2

#定義NACK 3

#定義請求文件100

#define命令不支持150

#定義命令支持160

#定義壞文件名200

#定義文件名OK 400

int writen(int sd,char *ptr,int size);

int readn(int sd,char *ptr,int size);

main() {

int sockid,newsd,pid,clilen

struct sockaddr_in my_addr,client _ addr

printf("服務器:正在創建套接字\ n ");

if ((sockid = socket(AF_INET,SOCK_STREAM,0))& lt;0)

{printf("服務器:套接字錯誤:%d\n ",errno);退出(0);}

printf("server:綁定我的本地套接字\ n ");

bzero((char *)& amp;my_addr,sizeof(my _ addr));

我的_地址. sin _家庭= AF _ INET

MY _ addr . sin _ PORT = htons(MY _ PORT _ ID);

my _ addr . sin _ addr . s _ addr = htons(in addr _ ANY);

if (bind(sockid,(struct sockaddr *)& amp;my_addr,sizeof(my _ addr))& lt;0)

{printf("服務器:綁定錯誤:%d\n ",errno);退出(0);}

printf("服務器:開始監聽\ n ");

if (listen(sockid,5)& lt;0)

{ printf(" server:listen error:% d \ n ",errno);退出(0);}

while(1==1) {

/*接受連接,然後創建壹個子進程來完成這項工作*/

/*環回並等待另壹個連接*/

printf("服務器:開始接受\ n ");

if ((newsd = accept(sockid,(struct sockaddr *)& amp;客戶端地址,

& ampclilen))& lt;0)

{printf("服務器:接受錯誤:%d\n ",errno);退出(0);}

printf("server:從accept返回,此ftp的套接字:%d\n ",

newsd);

if ( (pid=fork()) == 0) {

/*子過程從這裏開始。它將進行實際的文件傳輸*/

close(sockid);/*孩子不應該接受*/

doftp(newsd);

關閉(newsd);

退出(0);/*孩子全部完成工作*/

}

/*家長在下面繼續*/

關閉(newsd);/*父級全部由客戶端完成,只有子級*/

} /*從現在開始將與該客戶端通信*/

}

  • 上一篇:大遊戲的歷史
  • 下一篇:如何看待股市主力的“脈沖式操作手法”
  • copyright 2024編程學習大全網