青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

如何編寫Linux下的客戶機/服務器軟件

   Linux以其源代碼公開聞名于世,并以其穩定性和可靠性雄霸操作系統領域,在網絡應用技術方面使用得更加廣泛。很久以來它就是Windows的重要對手之一。隨著網絡時代的來臨,Linux的這種優勢已變得更加突出。本文將論述如何在Linux環境下利用Socket實現客戶機/服務器通信。
隨著網絡技術的發展,網絡結構已從過去的主機/終端型、對等型發展到現在廣為使用的客戶機/服務器型。客戶機/服務器模型應用十分廣泛,在Internet上WWW,E-mail,FTP等都是基于這種模型的。在面向連接的通信模式下,服務器打開監聽端口,監聽網絡上其它客戶機向該服務器發出的連接請求,當收到一個請求信號時與該客戶機建立一個連接,之后兩者進行交互式的通信。具體步驟可這樣組織:

服務器:
1.打開一個已知的監聽端口,如smtp為25、pop3為110、ftp為21、telnet為23等。
2.在監聽端口上監聽客戶機的連接請求,如果有客戶機請求連接則建立一個連接線路。
3.在連接線路上與客戶機通信。
4.通信完畢后關閉連接線路并繼續監聽客戶機的連接請求。

客戶機:
1.向指定的服務器主機及端口發出連接請求。
2.當服務器建立連接線路后與服務器進行通信。
3.通信完畢后關閉連接線路。

Linux的許多特性都非常有助于網絡程序設計:首先Linux擁有POSIX.1標準庫函數,socket()、bind()、listen()這幾個庫函數可以非常方便地實現服務器/客戶機模型,有關這幾個庫函數的使用說明將在后邊介紹。其次Linux的進程管理也非常符合服務器的工作原理,所謂進程就是程序在內存中運行時的狀態,可以說進程是動態的程序。在運行著Linux操作系統的計算機中,每一個進程都有一個創建它的父進程,而且它也能創建多個子進程。在服務器端我們可以用父進程去監聽客戶機的連接請求,當有客戶機的連接請求時父進程創建一個子進程去建立連接線路并與客戶機通信,而它本身可繼續監聽其它客戶機的連接請求,這樣就可避免當有一個客戶機與服務器建立連接后服務器就不能再與其它客戶機通信的問題。Linux的另一個特性是它秉承了UNIX設備無關性這一優秀特征,即它通過文件描述符實現了統一的設備接口,磁盤、顯示終端、音頻設備、打印設備甚至網絡通信都使用統一的I/O調用。這三個特性將使Linux下的網絡程序設計變得易如反掌。上述三個特性的綜合利用將是這篇文章所要講述的真諦所在。下邊的客戶機/服務器實現過程可以說明一二,注意與上文所述步驟的不同。

服務器:
1.打開一個已知的監聽端口。
2.在監聽端口上監聽客戶機的連接請求,當有一客戶機請求連接時建立連接線路并返回通信文件描述符。
4.父進程創建一子進程,父進程關閉通信文件描述符并繼續監聽端口上的客戶機連接請求。
3.子進程通過通信文件描述符與客戶機進行通信,通信結束后終止子進程并關閉通信文件描述符。

客戶機:
1.向指定的服務器主機及端口發出連接請求,請求成功將返回通信文件描述符。
2.通過通信文件描述符與服務器進行通信。
3.通信完畢后關閉通信文件描述符。


Linux的以下幾個庫函數是網絡程序設計的核心部分,它們分別是:
(1)socket
調用方式:
#include
#include

int socket(int domain,int type,int protocol);

簡要說明:
此函數為通信創建一個端口,正常調用將返回一個文件描述符,錯誤調用將返回-1。domain參數有兩種選擇:AF_UNIX與AF_INET,其中AF_INET為Internet通信協議。type參數也有兩種選擇:SOCK_STREAM用于TCP,SOCK_DGRAM用于UDP。protocol參數通常為0。可通過下列代碼為基于TCP協議的Internet通信建立套接口傳輸端口:

#include
#include
#include
int sock;

if((sock=socket(AF_INET,SOCK_STREAM,0))==-1)
perror("Could not create socket");

(2)bind
調用方式:
#include
#include

int bind(int s,const struct sockaddr *address,size_t address_len);

簡要說明:
bind英文含意是關聯,捆綁。其目的就是把socket返回的套接口端口與網絡上的物理位置相關聯。
bind正常調用返回0,出錯返回-1。此函數有三個參數:其中s為socket調用返回的文件描述符,*address設置了與網絡上的物理位置相關的信息,它的類型是struct sockaddr,但在Internet上它是struct sockaddr_in。在socket.h中struct sockaddr_in定義為:
struct sockaddr_in{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
sin_family一般為AF_INET,sin_port為端口號,由于使用不同字節順序的機器必須作轉換,故應使用宏命令htons(host to network short)來轉換端口號,sin_addr將置為INADDR_ANY。這三個值設置完成后*address參數才有意義。在編寫代碼時,應先設置*address參數內部各成員變量的值,再調用bind。

(3)listen
調用方式:
#include
#include

int listen(int s,int backlog);

簡要說明:
本函數使socket端口能夠接受從客戶機來的連接請求,正常調用返回0,出錯返回-1。
s參數為socket產生的文件描述符,backlog為所能接受客戶機的最大數目。
socket,bind,listen 三個函數的綜合調用最終在服務器上產生一個能接受客戶機請求的監聽文件描述符s。

(4)accept
調用方式:
#include
#include

int accept(int s,struct sockaddr *address,int *address_len);

簡要說明:
當有客戶機發出連接請求時,此函數初始化這個連接。正常調用返回與客戶機通信的通信文件描述符,出錯返回-1。參數s為socket調用返回的文件描述符,address將用來存儲客戶機的信息,此信息由accept填入,當與客戶機連接時,客戶機的地址與端口將填到此處。address_len是客戶機地址長度的字節數,也由accept填入。

(5)connect
調用方式:
#include
#include

int connect(int s,struct sockaddr *address,size_t address_len);

簡要說明:
客戶機調用socket建立傳輸端口后,調用connect來建立與遠程服務器相連的連接線路。
此函數的參數調用同bind。

(6)inet_addr
調用方式:
#include
#include
#include

in_addr_t inet_addr(const char *addstring);

簡要說明:
此函數將字符串addstring表示的網絡地址(如192.168.0.1)轉換成32位的網絡字節序二進制值,若成功返回32位二進制的網絡字節序地址,若出錯返回 INADDR_NONE。INADDR_NONE是32位均為1的值(即255.255.255.255,它是Internet的有限廣播地址),故如果要轉換的addstring是255.255.255.255,函數調用將失敗。

(7)fork
調用方式:
#include
#include


pid_t fork(void);

簡要說明:
fork的作用是拷貝父進程的內存映象來創建子進程,兩個進程將接著fork后的指令繼續執行。 事實上它返回兩個進程控制號,對于父進程它返回子進程的進程ID,對于子進程它返回0。

可用下邊的代碼調用fork:

pid_t childpid;
if((childpid=fork())=-1){
perror("The fork failed");
exit(1);
}
else if(child==0){
調用子進程;
}
else if(child>0){
調用父進程;
}


以上介紹了網絡編程的有關庫函數的調用方法,下面舉一個客戶機/服務器程序的小例子具體說明如何設計網絡程序。本例介紹如何查看服務器上的時間和日期,由于daytime服務器的通用端口為13,客戶機程序將通過調用13號端口對服務器上的時間和日期進行操作。
/*timeserve.c*/?
/*服務器程序偽代碼如下:?

打開daytime監聽端口;?
while(客戶機與服務器成功連接——成功返回通信文件描述符)?
{?
fork()?
子進程:?
{?
讀出當前時間;?
將當前時間寫入通信文件描述符;?
關閉通信文件描述符;?
}?
父進程:?
關閉通信文件描述符;?
}?
*/
?

#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?

int?main(int?argc,char?*argv[])?
{?
int?listenfd,communfd;?
struct?sockaddr_in?servaddr;?
pid_t?childpid;?
time_t?tick;?
char?buf[1024];?

if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)?
{?
perror(
"Could?not?create?socket");?
exit(
1);?
}
?

servaddr.sin_family
=AF_INET;?
servaddr.sin_addr.s_addr
=INADDR_ANY;?
servaddr.sin_port
=htons(13);?
if(bind(listenfd,(struct?sockaddr?*)&servaddr,sizeof(servaddr))==-1)?
{?
perror(
"bind?error");?
exit(
1);?
}
?
if(listen(listenfd,254)==-1)?
{?
perror(
"listen?error");?
exit(
1);?
}
?
while(communfd=accept(listenfd,(struct?sockaddr*)NULL,NULL))?
{?
if((childpid=fork())==-1)?
{?
perror(
"fork?error");?
exit(
1);?
}
?
else?if(childpid==0)?
{?
tick
=time(NULL);?
snprintf(buf,
sizeof(buf),"%.24s\r\n",ctime(&tick));?
write(communfd,buf,strlen(buf));?
close(communfd);?
}
?
else?if(childpid>0)?
close(communfd);?

}
?
exit(
0);?
}
?


/*timeclient.h*/?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?

int?main(int?argc,char?*argv[])?
{?
int?communfd,n;?
struct?sockaddr_in?servaddr;?
char?recieve[1024],buf[1024];?

if(argc!=2)?
{?
perror(
"Usage:?client?");?
exit(
1);?
}
?
if((communfd=socket(AF_INET,SOCK_STREAM,0))==-1)?
{?
perror(
"socket?error");?
exit(
1);?
}
?
servaddr.sin_family
=AF_INET;?
servaddr.sin_port
=htons(13);?
if((servaddr.sin_addr.s_addr=inet_addr(argv[1]))==INADDR_NONE)?
{?
perror(
"inet_addr?error");?
exit(
1);?
}
?
if(connect(communfd,(struct?sockaddr*)&servaddr,sizeof(servaddr))==-1)?
{?
perror(
"connect?error");?
exit(
1);?
}
?
while((n=read(communfd,recieve,1024))>0)?
{?
recieve[n]
=0;?
if(fputs(recieve,stdout)==EOF)?
perror(
"fputs?error");?
}
?
close(communfd);?
exit(
0);?
}
?
用gcc編譯兩個源程序分別取名為server和client,以根用戶身份運行服務器程序(設服務器網絡地址為192.168.0.1):
server &
然后運行客戶機程序(設服務器網絡地址為192.168.0.1):
client 192.168.0.1
在客戶機上就會反映出服務器上當前的時間如(Tue Feb 29 21:46:19 2000)。

以上程序代碼在redhat 6.0上試驗通過。在程序代碼中有關庫函數snprintf、fputs、read、write、close的用法就不在這里說明了,如想了解這些庫函數的調用方法可到我的網頁http://lzdx.yeah. net/pro_unix.html去查找。在我的網頁http://lzdx.yeah.net/pro_uici.html中有關于通用Internet接口(UICI)專用庫的介紹,通用Internet接口(UICI)利用Socket庫函數提供了一個簡化的獨立于傳輸的接口,它從整體上簡化了網絡程序設計過程。有興趣的人可到那里去看看。最后祝愿我們每個人都能編寫出自己的網絡程序。

posted on 2006-04-20 17:19 楊粼波 閱讀(835) 評論(0)  編輯 收藏 引用 所屬分類: 網絡編程

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产亚洲成av人在线观看导航| 久久天堂成人| 久久精品女人天堂| 亚洲人成在线免费观看| 欧美精品一区二区高清在线观看| 国产精品免费在线| 99国产精品久久久久久久| 久久蜜桃精品| 亚洲男人第一av网站| 欧美日韩在线三级| 一本色道**综合亚洲精品蜜桃冫| 亚洲高清视频一区二区| 亚洲深夜福利在线| 欧美日韩性视频在线| 中文一区二区在线观看| 亚洲日本欧美| 欧美三级电影大全| 亚洲欧美激情视频| 亚洲少妇诱惑| 国产一区二区三区久久久久久久久| 欧美在线播放视频| 久久gogo国模裸体人体| 精品不卡视频| 亚洲电影在线看| 欧美激情一区二区三区| 亚洲午夜精品久久久久久app| 日韩一级黄色av| 国产精品激情av在线播放| 小黄鸭视频精品导航| 欧美一级视频精品观看| 1000部国产精品成人观看| 欧美激情一区二区三区不卡| 欧美激情黄色片| 一本到12不卡视频在线dvd| 一本色道久久88综合日韩精品| 国产精品九九久久久久久久| 欧美在线观看一区二区三区| 久久av一区二区三区亚洲| 亚洲人成艺术| 亚洲伊人第一页| 一区二区三区在线不卡| 亚洲第一综合天堂另类专| 国产精品v片在线观看不卡| 久久久久久9| 欧美激情综合五月色丁香| 欧美一区二区观看视频| 欧美成人日韩| 久久久精品久久久久| 欧美美女视频| 久热精品视频| 国产精品毛片大码女人| 欧美激情一区二区三区不卡| 国产精品区二区三区日本| 欧美激情成人在线视频| 国产精品一卡| 亚洲精品乱码久久久久久黑人| 国产麻豆综合| 欧美亚洲三区| 亚洲乱码日产精品bd| 欧美午夜不卡视频| 久久亚洲综合色一区二区三区| 欧美a级片一区| 久久av二区| 欧美日韩www| 黄网站色欧美视频| 日韩午夜一区| 亚洲精品视频在线观看免费| 欧美激情日韩| 99精品国产高清一区二区| 亚洲国产精品久久久| 欧美国产日韩一区| 正在播放日韩| 亚洲欧美韩国| 国产综合色精品一区二区三区| 久久久国产精品亚洲一区| 欧美一区二区三区免费看 | 亚洲伊人伊色伊影伊综合网| 欧美日本在线看| 亚洲一级特黄| 亚洲欧美99| 极品日韩久久| 亚洲国产老妈| 国产精品成人一区二区艾草| 欧美一区二区三区婷婷月色 | 亚洲欧美乱综合| 亚洲女与黑人做爰| 黄色一区二区三区| 亚洲国产精品成人| 国产精品天天看| 久久性天堂网| 欧美日韩三区四区| 久久久久久午夜| 欧美电影免费| 欧美一级理论性理论a| 久久夜色精品国产欧美乱| 日韩亚洲综合在线| 性18欧美另类| 中文精品在线| 久久er精品视频| 中国日韩欧美久久久久久久久| 性欧美1819sex性高清| 亚洲激情一区二区| 亚洲亚洲精品在线观看| 亚洲国产精品一区二区第四页av | 日韩亚洲欧美综合| 国产日韩综合| 亚洲最黄网站| 亚洲电影免费| 亚洲在线观看免费视频| 亚洲精品欧美| 久久黄色小说| 亚洲一区bb| 西瓜成人精品人成网站| 亚洲国产你懂的| 一区二区欧美日韩| 亚洲国产一区二区在线| 中文国产一区| 亚洲精品欧洲精品| 亚洲欧美日产图| 夜夜嗨av一区二区三区中文字幕 | 国产精品免费网站在线观看| 欧美成人69av| 国内外成人免费视频 | 亚洲第一精品在线| 国产精品自拍在线| 一区二区三区四区五区精品视频 | 亚洲全黄一级网站| 欧美在线国产精品| 欧美在线视频导航| 国产精品日本一区二区| 亚洲精品一区二区三区福利| 亚洲经典视频在线观看| 久久裸体视频| 久久久中精品2020中文| 国产精品网站在线观看| 一区二区三区鲁丝不卡| 亚洲一级高清| 国产精品高潮呻吟久久av无限| 亚洲精选久久| 一本色道久久综合狠狠躁的推荐| 你懂的国产精品永久在线| 欧美国产免费| 亚洲国产精品毛片| 欧美国产第一页| 亚洲精品久久久久久下一站| 日韩视频在线永久播放| 欧美美女视频| 亚洲一区二区免费视频| 亚洲欧美综合国产精品一区| 国产精品国产三级国产普通话99| 亚洲一区区二区| 久久久久久高潮国产精品视| 韩国成人理伦片免费播放| 久久婷婷蜜乳一本欲蜜臀| 亚洲第一天堂av| 在线亚洲国产精品网站| 国产精品免费一区二区三区在线观看| 亚洲欧美日韩专区| 老鸭窝毛片一区二区三区| 亚洲国产日韩欧美综合久久 | 亚洲免费一在线| 久久久久久久激情视频| 亚洲国产高清在线观看视频| 欧美国产一区二区| 夜夜嗨av色综合久久久综合网| 午夜在线一区二区| 在线观看日韩国产| 午夜日韩视频| 久久精品卡一| 韩日欧美一区二区| 久久综合色一综合色88| 亚洲精品免费在线观看| 欧美亚洲综合久久| 亚洲三级网站| 国产乱人伦精品一区二区| 久久久久久亚洲精品杨幂换脸| 亚洲第一区在线| 欧美在线三区| 一区二区电影免费在线观看| 国产视频在线观看一区 | 国产精品高潮呻吟久久| 久久成人免费电影| 亚洲裸体俱乐部裸体舞表演av| 欧美综合77777色婷婷| 日韩视频免费观看高清完整版| 国产精品亚洲综合一区在线观看| 欧美凹凸一区二区三区视频| 欧美一区二区三区视频免费播放| 亚洲免费高清| 欧美成人日本| 欧美亚洲系列| 一区二区三区国产精华| 亚洲第一色在线| 国产视频一区二区三区在线观看| 欧美日韩成人激情| 欧美成人午夜免费视在线看片| 亚洲欧美一区二区在线观看| 一个人看的www久久| 亚洲欧洲三级| 欧美国产日韩一区二区在线观看|