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