網絡程序設計linux服務器課程設計報告_第1頁
已閱讀1頁,還剩17頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、<p><b>  網絡程序設計</b></p><p><b>  課程設計報告</b></p><p>  第1章 課程設計目的、要求</p><p><b>  1.1課程設計目的</b></p><p>  1.熟練掌握所學到的網絡套接字函數。</p&g

2、t;<p>  2.掌握UDP和TCP編程關鍵函數。</p><p>  3.掌握多進程或多線程編程。</p><p>  4.掌握使用select實現I/O復用。</p><p>  5.掌握守護進程的編寫。</p><p><b>  1.2實驗要求</b></p><p>  

3、1.認真閱讀和掌握本實驗的相關的知識點。</p><p>  2.上機編寫并運行程序。</p><p><b>  1.3實驗內容</b></p><p>  實現一個并發(fā)、IO復用的守護進程時間服務器,要求當客戶端向服務器發(fā)送“what’s time?”字符串時,服務器回應當時的系統(tǒng)時間字符串。</p><p><

4、;b>  1.4小組分工</b></p><p>  第2章 課程設計分析及內容</p><p><b>  2.1所用知識點</b></p><p>  2.1.1套接字函數</p><p> ?、倏蛻舳怂煤瘮担簊ocket()函數、connect()函數、send()函數、recv()函數,clo

5、se()函數。</p><p> ?、诜掌鞫怂煤瘮担篵ind()函數、socket()函數、listen()函數、accept()函數、send()函數、accept()函數、recv()函數、close()函數。</p><p><b>  2.1.2守護進程</b></p><p>  守護進程,也就是通常說的Daemon進程,是Lin

6、ux中的后臺服務進程。它是一個生存期較長的進程,通常獨立于控制終端并且周期性地執(zhí)行某種任務或等待處理某些發(fā)生的事件。守護進程常常在系統(tǒng)引導裝入時啟動,在系統(tǒng)關閉時終止。Linux系統(tǒng)有很多守護進程,大多數服務都是通過守護進程實現的。</p><p>  每一個從此終端開始運行的進程都會依附于這個終端,這個終端就稱為這些進程的控制終端,當控制終端被關閉時,相應的進程都會自動關閉。但是守護進程卻能夠突破這種限制,它從

7、被執(zhí)行開始運轉,直到整個系統(tǒng)關閉時才退出。如果想讓某個進程不因為用戶或終端或其他地變化而受到影響,那么就必須把這個進程變成一個守護進程。</p><p>  2.1.3 I/O復用</p><p>  I/O復用調用select或poll,并在該函數上阻塞,等待數據報套接口可讀;當select返回可讀條件時,調用recvfrom將數據報拷貝到應用程序緩沖區(qū)中。</p><

8、;p><b>  主要應用:</b></p><p> ?。?)客戶程序需要同時處理交互式的輸入和服務器之間的網絡連接。</p><p> ?。?)客戶端需要對多個網絡連接作出反應。</p><p> ?。?)TCP服務器需要同時處理多個處于監(jiān)聽狀態(tài)和多個連接狀態(tài)的套接字。</p><p> ?。?)服務器需要處理

9、多個網絡協議的套接字。</p><p> ?。?)服務器需要同時處理不同的網絡服務和協議。</p><p>  2.1.4 并發(fā)服務器</p><p>  不同于順序服務器,并發(fā)服務器就要能在一個時間為多個客戶端提供服務。 例如,一個聊天服務器可能服務一個特定的客戶端數小時──在停止為這個客戶端服務之前服務器不能等待, 除非是在等待一下個客戶端到來之前的間隙才能等待

10、。</p><p>  第3章 課程設計的實現</p><p>  3.1 程序運行步驟</p><p>  對于服務器端而言,由于它是一個守護進程所以只要做到接收信息并且存儲在一個數組中即可而不必在前臺顯示,對于客戶端必須有信息的發(fā)送和接收。服務器端必須對來自客戶端的信息加以判斷。</p><p>  如果接收到的字符串與“what’s_

11、time?”字符串行匹配那么則返回給客戶端一個系統(tǒng)的時間信息,否則返回給客戶端“Input error”的字符串。</p><p><b>  如下圖所示:</b></p><p><b>  圖3-1連接流程圖</b></p><p>  3.2 客戶端主要函數</p><p>  3.2.1 s

12、ocket()函數</p><p>  socket()函數用于根據指定的地址族、數據類型和協議來分配一個套接口的描述字及其所用的資源。</p><p>  創(chuàng)建一個套接口,代碼如下: </p><p>  #include <winsock.h> </p><p>  SOCKET PASCAL FAR socket( int

13、af, int type, int protocol); </p><p>  Af是一個地址描述。目前僅支持AF_INET格式,也就是說ARPA Internet地址格式,Type是新套接口的類型描述,protocol:套接口所用的協議,如調用者不想指定,可用0指定,表示缺省。</p><p>  3.2.2 connect()函數</p><p>  本函數用于

14、創(chuàng)建與指定外部端口的連接。s參數指定一個未連接的數據報或流類套接口。如套接口未被捆綁,則系統(tǒng)賦給本地關聯一個唯一的值,且設置套接口為已捆綁。請注意若名字結構中的地址域為全零的話,則connect()將返回WSAEADDRNOTAVAIL錯誤。</p><p>  返回值:若無錯誤發(fā)生,則connect()返回0。否則的話,返SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError()獲取相應錯誤

15、代碼。</p><p>  創(chuàng)建一個連接,代碼如下:</p><p>  #include <winsock.h> //調用套接字</p><p>  int PASCAL FAR connect( SOCKET s, const struct sockaddr FAR* name,int namelen);</p><p> 

16、 s是標識一個未連接套接口的描述字。</p><p>  Name是欲進行連接的端口名。</p><p>  Namelen是名字長度。</p><p><b>  3.3服務端函數</b></p><p>  3.3.1 send函數和recv函數</p><p><b>  1.se

17、nd函數</b></p><p>  int send( SOCKET s,const char FAR *buf,int len,int flags ); </p><p>  不論是客戶還是服務器應用程序都用send函數來向TCP連接的另一端發(fā)送數據。</p><p>  客戶程序一般用send函數向服務器發(fā)送請求,而服務器則通常用send函數來向

18、客戶程序發(fā)送應答。</p><p>  第一個參數指定發(fā)送端套接字描述符。</p><p>  第二個參數指明一個存放應用程序要發(fā)送數據的緩沖區(qū)。</p><p>  第三個參數指明實際要發(fā)送的數據的字節(jié)數。</p><p>  第四個參數一般置0。</p><p><b>  2.recv函數</b&

19、gt;</p><p>  int recv( SOCKET s,char FAR *buf,int len, int flags); </p><p>  不論是客戶還是服務器應用程序都用recv函數從TCP連接的另一端接收數據。</p><p>  第一個參數指定接收端套接字描述符。</p><p>  第二個參數指明 一個緩沖區(qū),該

20、緩沖區(qū)用來存放recv函數接收到的數據。</p><p>  第三個參數指明buf的長度。</p><p>  第四個參數一般置0。</p><p>  3.3.2 close()函數</p><p>  close函數用于關閉套接字,并立即返回到進程。關閉后的套接字描述符不能再接收和發(fā)送數據,再不能作為函數send()或recv()的參數。

21、如果套接字描述符訪問計數在調用close后大于0(在多個進程共享同一個套接字的情況下),則不會引發(fā)TCP終止序列(即不會發(fā)送FIN分節(jié))。</p><p>  3.3.3 select函數</p><p>  select()的機制中提供一fd_set的數據結構,實際上是一long類型的數組, 每一個數組元素都能與一打開的文件句柄(不管是Socket句柄,還是其他 文件或命名管道或設備句柄

22、)建立聯系,建立聯系的工作由程序員完成, 當調用select()時,由內核根據IO狀態(tài)修改fd_set的內容,由此來通知執(zhí) 行了select()的進程哪一Socket或文件可讀。</p><p>  3.4 創(chuàng)建守護進程</p><p><b>  創(chuàng)建步驟:</b></p><p><b>  ①使進程在后臺運行</b>

23、</p><p> ?、诿撾x控制終端,登錄會話和進程組(創(chuàng)建新會話)</p><p>  ③禁止進程重新打開控制終端</p><p> ?、荜P閉所有文件描述符</p><p><b> ?、莞淖儺斍肮ぷ髂夸?lt;/b></p><p><b>  ⑥重設權限掩碼</b></

24、p><p> ?、咛幚鞸IGCHLD信號</p><p><b>  心得體會</b></p><p>  經過兩周的課程設計,我們對Linux有了更深的體會,意識到只有動手去操作才能真的掌握它。同樣也對服務器有了多重的認識,認識到其在生活中的重要性,和我們的生活密不可分。</p><p>  時間服務器更是重中所重,時間的

25、重要性越來越大,時間服務器作為時間的核心其重要性已經不言而喻,且開發(fā)成本較小,用時較少,易于開發(fā)。不僅為我們以后的程序生涯打好基礎,也能增加我們對編寫程序的興趣。</p><p>  這次之后,我們小組還算是比較默契的。沒想到這項看起來不需要多少技術的工作卻是非常需要耐心和精力,在兩周后的今天我已明白課程設計對我來說的意義,它不僅僅是讓我們把所學的理論知識與實踐相結合起來,提高自己的實際動手能力和獨立思考的能力,

26、更重要的是同學間的團結,雖然我們這次花去的時間比別人多,但我相信我們得到的也會更多。</p><p>  在這次課程設計中,我們運用到了以前所學的專業(yè)課知識,比如并發(fā)服務器原理,I/O復用技術,守護進程的創(chuàng)建。正如孔子所說:“溫故而知新”,我們在開發(fā)的過程中有時會遇到問題,等到解決之后,發(fā)現自己知道了更多的東西,對知識點有了更深刻的理解。</p><p>  這也激發(fā)了我今后努力學習的興趣

27、,我想這將對我以后的學習產生積極的影響。其次,這次課程設計讓我充分認識到團隊合作的重要性,只有分工協作才能保證整個項目的有條不絮。另外在課程設計的過程中,當我們碰到不明白的問題時,指導老師總是耐心的講解,給我們的設計以極大的幫助,使我們獲益匪淺。因此非常感謝老師的教導。</p><p><b>  附錄一 系統(tǒng)界面 </b></p><p><b>  附錄

28、二 程序代碼</b></p><p><b>  客戶端程序:</b></p><p>  #include <stdio.h></p><p>  #include <stdlib.h></p><p>  #include <string.h></p>&

29、lt;p>  #include <unistd.h></p><p>  #include <sys/socket.h></p><p>  #include <netinet/in.h></p><p>  #include <netdb.h></p><p>  #define POR

30、T 1234</p><p>  #define MAXDATASIZE 100</p><p>  #define MAXLINE 100</p><p>  int main(int argc,char * argv[])</p><p><b>  {</b></p><p>  int

31、 fd,numbytes;</p><p>  char buf[MAXDATASIZE],sendline[MAXLINE];</p><p>  struct hostent * he;</p><p>  struct sockaddr_in server;</p><p>  if (argc != 3) {</p>

32、<p>  fprintf(stderr,"usage: %s <IP>address and myport\n", argv[0]);</p><p><b>  exit(1);</b></p><p><b>  }</b></p><p>  if((he=gethostb

33、yname(argv[1]))==NULL){</p><p>  perror("gethostbyname error.");</p><p><b>  exit(-1);</b></p><p><b>  }</b></p><p>  if((fd=socket(AF

34、_INET,SOCK_STREAM,0))==-1){</p><p>  perror("Create socket failed"); </p><p><b>  exit(1);</b></p><p><b>  }</b></p><p>  else print

35、f("Connect Success!\n");</p><p>  bzero(&server,sizeof(server));</p><p>  server.sin_family=AF_INET;</p><p>  server.sin_port=htons(PORT);</p><p>  server

36、.sin_addr=*((struct in_addr *)he->h_addr);</p><p>  if(connect(fd,(struct sockaddr *)&server,sizeof(struct sockaddr))==-1) {</p><p>  perror("Bind error.");</p><p>

37、<b>  exit(1);</b></p><p><b>  }</b></p><p>  if((numbytes=recv(fd,buf,MAXDATASIZE,0))==-1) {</p><p>  perror("recv error.");</p><p>&

38、lt;b>  exit(1);</b></p><p><b>  }</b></p><p>  buf[numbytes]='\0';</p><p>  printf("Server Message: %s\n",buf); </p><p>  close

39、(fd);</p><p><b>  }服務器端程序:</b></p><p>  #include <unistd.h></p><p>  #include <stdio.h></p><p>  #include <syslog.h></p><p>

40、  #include <signal.h></p><p>  #include <sys/types.h></p><p>  #include <sys/socket.h></p><p>  #include <sys/select.h></p><p>  include <arp

41、a/inet.h></p><p>  #define PORT 1234</p><p>  #define BACKLOG 5</p><p>  #define MAXLINE 255</p><p>  #define MAXFD 64</p><p>  void demon_init(const ch

42、ar *pname,int facility)</p><p><b>  {</b></p><p><b>  int i;</b></p><p>  pid_t pid;</p><p>  if((pid=fork())!=0)</p><p><b> 

43、 exit(0);</b></p><p><b>  setsid();</b></p><p>  signal(SIGHUP,SIG_IGN);</p><p>  if((pid=fork())!=0)</p><p><b>  exit(0);</b></p>

44、<p>  chdir("/");</p><p><b>  umask(0);</b></p><p>  for(i=0;i<MAXFD;i++)</p><p><b>  close(i);</b></p><p>  openlog(pname,LOG

45、_PID,facility);</p><p><b>  }</b></p><p>  int main(int argc,char **argv)</p><p><b>  {</b></p><p>  int listenfd,connfd;</p><p>  

46、socklen_t addrlen,len;</p><p>  struct sockaddr_in client_addr;</p><p>  struct sockaddr_in server;</p><p>  char buff[MAXLINE];</p><p>  time_t ticks;</p><p

47、>  bzero(&server,sizeof(server));</p><p>  bzero(&client_addr,sizeof(client_addr));</p><p>  server.sin_family=AF_INET;</p><p>  server.sin_port=htons(1234);</p>&

48、lt;p>  server.sin_addr.s_addr=htonl(INADDR_ANY);</p><p>  demon_init(argv[0],0);</p><p>  if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)</p><p><b>  {</b></p>

49、<p>  syslog(LOG_NOTICE|LOG_LOCAL0,"socket error");</p><p><b>  exit(-1);</b></p><p><b>  }</b></p><p>  if(bind(listenfd,(struct sockaddr *

50、)&server,sizeof(struct sockaddr))==-1)</p><p><b>  {</b></p><p>  syslog(LOG_NOTICE|LOG_LOCAL0,"socket error");</p><p><b>  exit(-1);</b></p

51、><p><b>  }</b></p><p>  if(listen(listenfd,BACKLOG)==-1)</p><p><b>  {</b></p><p><b>  exit(-1);</b></p><p><b>  }&

52、lt;/b></p><p><b>  for(;;){</b></p><p>  len=sizeof(client_addr);</p><p>  connfd=accept(listenfd,&client_addr,&len);</p><p>  ticks=time(NULL);&

53、lt;/p><p>  snprintf(buff,sizeof(buff),"%.24s\r\n",ctime(&ticks));</p><p><b>  int a;</b></p><p>  if((a=write(connfd,buff,strlen(buff)))==-1)</p><

54、p><b>  {</b></p><p>  syslog(LOG_NOTICE|LOG_LOCAL0,"write error");</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p> 

55、 int fd_A[BACKLOG]; </p><p>  int conn_amount; </p><p><b>  int ret;</b></p><p>  int i,new_fd;</p><p>  fd_set fdsr;</p><p>  int maxsock;

56、</p><p>  struct timeval tv; </p><p>  conn_amount = 0; </p><p>  maxsock = listenfd;</p><p>  while (1) {</p><p>  FD_ZERO(&fdsr);</p><p&

57、gt;  FD_SET(listenfd, &fdsr);</p><p>  tv.tv_sec = 30;</p><p>  tv.tv_usec = 0;</p><p>  for (i = 0; i < BACKLOG; i++) {</p><p>  if (fd_A[i] != 0) {</p>

58、<p>  FD_SET(fd_A[i], &fdsr);</p><p><b>  }</b></p><p><b>  }</b></p><p>  ret = select(maxsock + 1, &fdsr, NULL, NULL, &tv);</p><

59、;p>  if (ret < 0) {</p><p>  perror("select");</p><p><b>  break;</b></p><p>  } else if (ret == 0) {</p><p>  printf("timeout\n")

60、;</p><p><b>  continue;</b></p><p><b>  }</b></p><p>  for (i = 0; i < conn_amount; i++) {</p><p>  if (FD_ISSET(fd_A[i], &fdsr)) {</p

61、><p>  ret = recv(fd_A[i], buff, sizeof(buff), 0);</p><p>  if (ret <= 0) { </p><p>  printf("client[%d] close\n", i);</p><p>  close(fd_A[i]);</p>&l

62、t;p>  FD_CLR(fd_A[i], &fdsr);</p><p>  fd_A[i] = 0;</p><p>  } else { </p><p>  if (ret < MAXLINE)</p><p>  memset(&buff[ret], '\0', 1);</p&g

63、t;<p>  printf("client[%d] send:%s\n", i, buff);</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  if

64、(FD_ISSET(listenfd, &fdsr)) {</p><p>  new_fd = accept(listenfd, (struct sockaddr *)&client_addr, &len);</p><p>  if (new_fd <= 0) {</p><p>  perror("accept"

65、;);</p><p><b>  continue;</b></p><p><b>  }</b></p><p>  if (conn_amount < BACKLOG) {</p><p>  fd_A[conn_amount++] = new_fd;</p><p

66、>  printf("new connection client[%d] %s:%d\n", conn_amount,</p><p>  inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));</p><p>  if (new_fd > maxsock)</p><

67、p>  maxsock = new_fd;</p><p><b>  }</b></p><p><b>  else {</b></p><p>  printf("max connections arrive, exit\n");</p><p>  send(new

68、_fd, "bye", 4, 0);</p><p>  close(new_fd);</p><p><b>  break;</b></p><p><b>  }</b></p><p><b>  } </b></p><p>

69、;<b>  }</b></p><p>  for (i = 0; i < BACKLOG; i++) {</p><p>  if (fd_A[i] != 0) {</p><p>  close(fd_A[i]);</p><p><b>  }</b></p><p

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論