請閱讀以下說明和Socket程序,填入(n)處。 網(wǎng)絡(luò)應(yīng)用的基本模型是客戶機(jī)/服務(wù)器模型,這是一個(gè)不對稱
請閱讀以下說明和Socket程序,填入(n)處。
網(wǎng)絡(luò)應(yīng)用的基本模型是客戶機(jī)/服務(wù)器模型,這是一個(gè)不對稱的編程模型,通信的雙方扮演不同的角色:客戶機(jī)和服務(wù)器。本題中的程序,客戶機(jī)接收用戶在鍵盤上輸入的文字內(nèi)容,服務(wù)器將客戶機(jī)發(fā)送來的文字內(nèi)容直接返回給客戶機(jī)。
此程序中,用戶自定義函數(shù)有:
int read_all( int fd, void*buf, int nbyte );
函數(shù)read all從參數(shù)fd指定的套接字描述符中讀取nbytes字節(jié)數(shù)據(jù)至緩沖區(qū)buf中,成功返回實(shí)際讀的字節(jié)數(shù)(可能小于nbyte),失敗返回-1。
int write_all( int fd, void*buf, int nbyte );
函數(shù)write_all向參數(shù)fd指定的套接字描述符中寫入緩沖區(qū)buf前nbyte字節(jié)的數(shù)據(jù),成功返回實(shí)際寫的字節(jié)數(shù)(始終等于nbyte),失敗返回-1。
write_requ函數(shù)為客戶機(jī)發(fā)送請求的函數(shù);read_requ函數(shù)為服務(wù)器獲取請求的函數(shù)
服務(wù)器主程序部分:
define SERVER_PORT 8080 //服務(wù)器監(jiān)聽端口號(hào)為8080
define BACKLOG 5 //連接請求隊(duì)列長度
int main( int argc, char*argv[]) {
int listenfd, connfd //監(jiān)聽套接字、連接套接字描述符
struct sockaddr_in servaddr; //服務(wù)器監(jiān)聽地址
listenfd=(1); //創(chuàng)建用于監(jiān)聽的套接字
if (listenfd<0) {
fPrintf( stderr,"創(chuàng)建套接字錯(cuò)誤!");
exit(1);
} //套接字創(chuàng)建失敗時(shí)打印錯(cuò)誤信息
bzero(&servaddr.sizeof(servadd));//將地址結(jié)構(gòu)置空
servaddr.sin_family=AF_INET;//設(shè)置地址結(jié)構(gòu)遵循TCP/IP協(xié)議
servaddr.sin_addrs_addr=htonl.(2);//設(shè)置監(jiān)聽的IP地址為任意合法地址,并將該地址轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序
servaddr.sin_port=(3);//設(shè)置監(jiān)聽的端口,并轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)順序
if ( bind(4)<0 ) {
fprintf( stderr,"綁定套接字與地址!");
exit(1);
} //將監(jiān)聽地址與用于監(jiān)聽的套接字綁定,綁定失敗時(shí)打印錯(cuò)誤信息
if ( listen( listedfd, BACKLOG)<0) {
fprintf( stderr,"轉(zhuǎn)換套接字為監(jiān)聽套接字!");
exit(1);
} //將用于監(jiān)聽的套接字由普通套接字轉(zhuǎn)化為監(jiān)聽套接字
for(;){
connfd=(5);
//從監(jiān)聽套接字的連接隊(duì)列中接收已經(jīng)完成的連接,并創(chuàng)建新的連接套接字
if(connfd<0){
fprintf(stderr,"接收連接失敗!");
exit(1);
} //接收失敗打印錯(cuò)誤信息
serv_respon(connfd); //運(yùn)行服務(wù)器的處理函數(shù)
(6);//關(guān)閉連接套接字 }
close(listenfd);//關(guān)閉監(jiān)聽套接字 }
服務(wù)器通信部分:
include<stdio.h>
……//引用頭文件部分略>
void serv_respon( int sockfd) {
int nbytes; char buf[1024];
for(;;) {
nbytes=read_requ(sockfd, buf, 1024);
//讀出客戶機(jī)發(fā)出的請求,并分析其中的協(xié)議結(jié)構(gòu),獲知請求的內(nèi)容部分的長度,并將內(nèi)容復(fù)制到緩沖區(qū)buf中,
if ( nbytes=0) return;//如客戶機(jī)結(jié)束發(fā)送就退出
else if ( bytes<0 ) {
fprintf( siderr,"讀錯(cuò)誤情息:%s\n", sterror( errno ));
return;
}//讀請求錯(cuò)誤打印錯(cuò)誤信息
if ( write_all ( sockfd, buf, nbytes)<0)
//將請求中的內(nèi)容部分反向發(fā)送回客戶機(jī)
fprintf( siderr,"寫錯(cuò)誤信息:%s\n", strerror( errno ) );
}
}
int read_requ( int sockfd, char*buf int size ) {
char inbuf[256];
int n; int i;
i=read_line( sockfd, inbuf, 256 );
//從套接字接收緩沖區(qū)中讀出一行數(shù)據(jù),該數(shù)據(jù)為客戶請求的首部
if(1<O)return(1);
else if ( i=0 ) return(0);
if ( strncmp( inbuf,"",6 )=0)
sscanf( (7),"%d", &n );//從緩沖區(qū)buf中讀出長度信息
else{
sprintf( buf," ",14 );
return(14);
}//取出首部Length域中的數(shù)值,該數(shù)值為內(nèi)容部分的長度
return( read_all( sockfd, buf, n ) );//從接收緩沖區(qū)中讀出請求的內(nèi)容部分
}
int get_char(int fd, char*ch) {
static int ffset=0;
static int size=0;
static char buff[1024];
//聲明靜態(tài)變量,在get_char多次被調(diào)用期間,該變量的內(nèi)存不釋放
for ( ;size<=0 ||(8);) {
size=read(fd,buf,1024);//一次從套接字緩沖區(qū)中讀出一個(gè)數(shù)據(jù)塊
if ( size<0 ) {
if ( errno=EINTR ) {
size=0;
confine;
//EINTR表示本次讀操作沒有成功,但可以繼續(xù)使用該套接字讀出數(shù)i
}else
return(-1);
}
ffset=0;//讀出數(shù)據(jù)后,將偏址置為0
}
*ch=buf[(9)];//將當(dāng)前的字符取出,并將偏址移向下一字符
return(1);
}
int read_line(int fd, char*buf, int maxlen) {
int i,n;
char ch;
for ( i=0; i<maxlen;) {
n = get_char( fd, &ch );//取出一個(gè)字符
if ( n==1 ){
buff[i++]=ch;//將字符加入字符串中
if ( (10) break;
}else if ( n< ) return(-1);
else break;
}
buf[i]='\0';
return(i);
}
//函數(shù)read_line的作用
正確答案:(1)socket(AF_INET SOCK_STREAM 0)(2)INADDR_ANY(3)htons(SERVER_PORT)(4)listenfd (struct sockaddr*)&servaddr sizeof(servaddr)(5)accept(listenfd NULL NULL)(6)close(connfd)(7)buf 6(8)offset==size(9)offset++(10)ch=‘\n’(1)socket(AF_INET, SOCK_STREAM, 0)(2)I
詞條內(nèi)容僅供參考,如果您需要解決具體問題
(尤其在法律、醫(yī)學(xué)等領(lǐng)域),建議您咨詢相關(guān)領(lǐng)域?qū)I(yè)人士。