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

tqsheng

go.....
隨筆 - 366, 文章 - 18, 評論 - 101, 引用 - 0
數據加載中……

多進程并發服務器編程


一、實驗目的

理解進程的創建和終止方法;

熟悉父進程與子進程對描述符的操作過程;

學會編寫基本的多進程并發服務器程序和客戶程序。

二、實驗平臺

ubuntu-8.04操作系統

三、實驗內容

編寫多進程并發服務器程序和客戶程序,具體功能如下:

1、服務器等待接收客戶的連接請求,一旦連接成功則顯示客戶地址,接著接收客戶端的名稱并顯示;然后接收來自該客戶的字符串,每當收到一個字符串時,顯示該字符串,并將字符串按照愷撒密碼的加密方式(K=3)進行加密,再將加密后的字符發回客戶端;之后,繼續等待接收該客戶的信息,直到客戶關閉連接。要求服務器具有同時處理多個客戶請求的能力。

2、客戶首先與相應的服務器建立連接;接著接收用戶輸入的客戶端名稱,并將其發送給服務器;然后繼續接收用戶輸入的字符串,再將字符串發送給服務器,同時接收服務器發回的加密后的字符串并顯示。之后,繼續等待用戶輸入字符串,直到用戶輸入Ctrl+D,客戶關閉連接并退出。

四、實驗原理

前面所實現的服務器/客戶程序中,服務器每次只能處理一個客戶的請求,他雖然很簡單但效率低下。在實際應用中,這樣的服務器不能滿足實際需求,并發技術可以極大地提高服務器的處理能力和響應速度。

TCP并發服務器的工作流程見圖6.1所示:

6.1TCP并發服務器

1、創建進程

可以通過調用forkvfork函數來創建新進程。

1fork函數

-------------------------------------------------------------------
#include<sys/types.h>

#include <unistd.h>

pid_t fork(void)

返回:父進程中返回子進程的進程ID,子進程返回0-1出錯

-------------------------------------------------------------------


  • fork后,子進程和父進程繼續執行fork()函數后的指令。子進程是父進程的副本。子進程擁有父進程的數據空間、堆棧的副本。但父、子進程并不共享這些存儲空間部分。如果代碼段是只讀的,則父子進程共享代碼段。如果父子進程同時對同一文件描述字操作,而又沒有任何形式的同步,則會出現混亂的狀況;

  • 父進程中調用fork之前打開的所有描述字在函數fork返回之后子進程會得到一個副本。fork后,父子進程均需要將自己不使用的描述字關閉。

2vfork函數

-------------------------------------------------------------------
#include<sys/types.h>

#include <unistd.h>

pid_tvfork(void)

返回:父進程中返回子進程的進程ID,子進程返回0-1出錯

-------------------------------------------------------------------


  • forkvfork函數的基本區別在于當使用vfork()創建新進程時,父進程將被暫時阻塞,而子進程則可以借用父進程的地址空間,直到子進程退出,至此父進程才繼續執行。

2、終止進程

進程的終止存在兩個可能:

1)父進程先于子進程終止;

2)子進程先于主進程終止。

  • 對于后者,系統內核為子進程保留一定的狀態信息:進程ID、終止狀態、CPU時間等;當父進程調用waitwaitpid函數時,獲取這些信息。

  • 當子進程正常或異常終止時,系統內核向其父進程發送SIGCHLD信號;缺省情況下,父進程忽略該信號,或者提供一個該信號發生時即被調用的函數。

exit()函數:

-------------------------------------------------------------------
#include<stdlib.h>

void exit(int status);

-------------------------------------------------------------------

exit()函數用于終止調用進程。關閉所有子進程打開的描述符,向父進程發送SIGCHLD信號,并返回狀態。

父進程可通過調用wait()waitpid()函數獲得子進程的終止信息。

wait()函數:

-------------------------------------------------------------------
#include<sys/types.h>

#include <sys/wait.h>

pid_t wait(int*stat_loc);

返回:終止子進程的ID-成功;-1-出錯;stat_loc存儲子進程的終止狀態(一個整數);

-------------------------------------------------------------------

如果沒有終止的子進程,但是有一個或多個正在執行的子進程,則該函數將堵塞,直到有一個子進程終止或者wait被信號中斷時,wait返回。

當調用該系統調用時,如果有一個子進程已經終止,則該系統調用立即返回,并釋放子進程所有資源。


waitpid()函數:

-------------------------------------------------------------------
#include<sys/types.h>

#include <sys/wait.h>

pid_t waitpid(pid_t pid, int*stat_loc, int option);

返回:終止子進程的ID-成功;-1-出錯;stat_loc存儲子進程的終止狀態;-------------------------------------------------------------------


pid=-1,option=0時,該函數等同于wait,否則由參數pidoption共同決定函數行為,其中pid參數意義如下:

    • -1:要求知道任何一個子進程的返回狀態(等待第一個終止的子進程);

    • >0:要求知道進程號為pid的子進程的狀態;

    • <-1:要求知道進程號為pid的絕對值的子進程的終止狀態

Option最常用的選項是WNOHANG,它通知內核在沒有已終止進程時不要堵塞。

調用waitwaitpid函數時,正常情況下,可能會有以下幾種情況:

    • 阻塞(如果其所有子進程都還在運行);

    • 獲得子進程的終止狀態并立即返回(如果一個子進程已終止,正等待父進程存取其終止狀態);

    • 出錯立即返回(如果它沒有任何子進程)


五、實驗步驟

1、登陸進入ubuntu操作系統,新建一個文件,命名為mproc_server.c,新建另一個文件,命名為mproc_client.c

2、在mproc_server.cmproc_client.c中編寫相應代碼并保存。

3、打開一個終端,執行命令進入mproc_server.cmproc_client.c所在目錄。

4、執行命令gccomproc_servermproc_server.c生成可執行文件mproc_server

5、執行命令gccomproc_clientmproc_client.c生成可執行文件mproc_client

6、執行命令./mproc_server,運行服務器端。

7、打開第2終端,執行命令進入mproc_server.cmproc_client.c所在目錄。

8、執行命令./mproc_client127.0.0.1,模擬客戶1

9、打開第3終端,執行命令進入mproc_server.cmproc_client.c所在目錄。

10、執行命令./mproc_client127.0.0.1,模擬客戶2

11、程序運行結果如下:

服務器端:


客戶1



客戶2


12、在客戶端按下Ctrl+D,關閉客戶連接。

13、認真分析源代碼,體會多進程并發服務器程序的編寫。

六、參考程序

1mproc_server.c內容如下:

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <unistd.h>  
  5. #include <sys/types.h>  
  6. #include <sys/socket.h>  
  7. #include <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9.   
  10. #define PORT 1234  
  11. #define BACKLOG 5  
  12. #define MAXDATASIZE 1000  
  13. void process_cli(int  connfd, struct sockaddr_in client);  
  14.   
  15. main()  
  16. {  
  17. int  listenfd, connfd;  
  18. pid_t  pid;  
  19. struct  sockaddr_in  server;  
  20. struct sockaddr_in  client;  
  21. int  len;  
  22.   
  23. if ((listenfd =socket(AF_INET, SOCK_STREAM, 0)) == -1) {  
  24. perror("Creatingsocket failed.");  
  25. exit(1);  
  26. }  
  27.   
  28. int opt =SO_REUSEADDR;  
  29. setsockopt(listenfd,SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  
  30. bzero(&server,sizeof(server));  
  31. server.sin_family=AF_INET;  
  32. server.sin_port=htons(PORT);  
  33. server.sin_addr.s_addr= htonl (INADDR_ANY);  
  34. if (bind(listenfd,(struct sockaddr *)&server, sizeof(server)) == -1) {  
  35. perror("Bind()error.");  
  36. exit(1);  
  37. }  
  38.   
  39. if(listen(listenfd,BACKLOG)== -1){  
  40. perror("listen() error\n");  
  41. exit(1);  
  42. }  
  43. len=sizeof(client);  
  44.   
  45. while(1)  
  46. {  
  47. if ((connfd =accept(listenfd,(struct sockaddr *)&client,&len))==-1) {  
  48. perror("accept() error\n");  
  49. exit(1);  
  50. }  
  51. if ((pid=fork())>0){  
  52. close(connfd);  
  53. continue;  
  54. }  
  55. else if (pid==0) {  
  56. close(listenfd);  
  57. process_cli(connfd, client);  
  58. exit(0);  
  59. }  
  60. else {  
  61. printf("fork()error\n");  
  62. exit(0);  
  63. }  
  64. }  
  65. close(listenfd);  
  66. }  
  67.   
  68. void process_cli(int connfd, struct sockaddr_in client)  
  69. {  
  70. int num;  
  71. char  recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], cli_name[MAXDATASIZE];  
  72. printf("Yougot a connection from %s. ",inet_ntoa(client.sin_addr) );  
  73. num = recv(connfd,cli_name, MAXDATASIZE,0);  
  74. if (num == 0)  
  75. {  
  76. close(connfd);  
  77. printf("Client disconnected.\n");  
  78. return;  
  79. }  
  80. cli_name[num - 1] ='\0';  
  81. printf("Client'sname is %s.\n",cli_name);  
  82.   
  83. while (num =recv(connfd, recvbuf, MAXDATASIZE,0)) {  
  84. recvbuf[num] ='\0';  
  85. printf("Receivedclient( %s ) message: %s",cli_name, recvbuf);  
  86. int i = 0;  
  87. for (i = 0;i < num - 1; i++) {  
  88. if((recvbuf[i]>='a'&&recvbuf[i]<='z')||(recvbuf[i]>='A'&&recvbuf[i]<='Z'))  
  89. {  
  90. recvbuf[i]=recvbuf[i]+ 3;  
  91. if((recvbuf[i]>'Z'&&recvbuf[i]<='Z'+3)||(recvbuf[i]>'z'))  
  92. recvbuf[i]=recvbuf[i]- 26;  
  93. }  
  94. sendbuf[i] =recvbuf[i];  
  95. }  
  96. sendbuf[num - 1]= '\0';  
  97.   
  98. send(connfd,sendbuf,strlen(sendbuf),0);  
  99. }  
  100. close(connfd);  
  101. }  


 

2mproc_client.c內容如下:

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <string.h>  
  5. #include<sys/types.h>  
  6. #include<sys/socket.h>  
  7. #include<netinet/in.h>  
  8. #include <netdb.h>  
  9.   
  10. #define PORT 1234  
  11. #define MAXDATASIZE100  
  12. void process(FILE*fp, int sockfd);  
  13. char *getMessage(char* sendline,int len, FILE* fp);  
  14.   
  15. int main(int argc,char *argv[])  
  16. {  
  17. int fd;  
  18. struct hostent  *he;  
  19. struct sockaddr_in  server;  
  20.   
  21. if (argc !=2) {  
  22. printf("Usage:%s <IP Address>\n",argv[0]);  
  23. exit(1);  
  24. }  
  25.   
  26. if((he=gethostbyname(argv[1]))==NULL){  
  27. printf("gethostbyname() error\n");  
  28. exit(1);  
  29. }  
  30. if((fd=socket(AF_INET, SOCK_STREAM, 0))==-1){  
  31. printf("socket()error\n");  
  32. exit(1);  
  33. }  
  34.   
  35. bzero(&server,sizeof(server));  
  36. server.sin_family =AF_INET;  
  37. server.sin_port=htons(PORT);  
  38. server.sin_addr= *((struct in_addr *)he->h_addr);  
  39.   
  40. if(connect(fd,(struct sockaddr *)&server,sizeof(server))==-1){  
  41. printf("connect() error\n");  
  42. exit(1);  
  43. }  
  44.   
  45. process(stdin,fd);  
  46.   
  47. close(fd);  
  48. }  
  49.   
  50. void process(FILE *fp, int  sockfd)  
  51. {  
  52. char sendline[MAXDATASIZE],recvline[MAXDATASIZE];  
  53. int num;  
  54.   
  55. printf("Connected to server. \n");  
  56. printf("Input client's name : ");  
  57. if (fgets(sendline, MAXDATASIZE, fp) == NULL) {  
  58. printf("\nExit.\n");  
  59. return;  
  60. }  
  61. send(sockfd,sendline, strlen(sendline),0);  
  62. while(getMessage(sendline, MAXDATASIZE, fp) != NULL) {  
  63. send(sockfd,sendline, strlen(sendline),0);  
  64.   
  65. if ((num =recv(sockfd, recvline, MAXDATASIZE,0)) == 0) {  
  66. printf("Server terminated.\n");  
  67. return;  
  68. }  
  69.   
  70. recvline[num]='\0';  
  71. printf("Server Message: %s\n",recvline);  
  72.   
  73. }  
  74. printf("\nExit.\n");  
  75. }  
  76.   
  77. char  *getMessage(char*  sendline,int len, FILE*  fp)  
  78. {  
  79. printf("Inputstring to server:");  
  80. return(fgets(sendline,MAXDATASIZE, fp));  
  81. }  

 

posted on 2012-07-05 14:24 tqsheng 閱讀(577) 評論(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>
            欧美一区二区三区喷汁尤物| 亚洲国产一区二区精品专区| 亚洲影音一区| 亚洲午夜一区二区| 国产精品一区久久久| 性欧美暴力猛交另类hd| 性视频1819p久久| 国产永久精品大片wwwapp| 久久亚洲春色中文字幕久久久| 久久这里只有精品视频首页| 亚洲麻豆视频| 亚洲一区二区综合| 一区二区在线不卡| 亚洲美女中出| 激情一区二区三区| 日韩视频二区| 在线日韩中文| 亚洲午夜久久久久久尤物 | 欧美成人免费观看| 亚洲欧美在线观看| 久久婷婷国产综合精品青草| 亚洲伦理在线观看| 亚洲欧美影院| 99在线热播精品免费| 久久精品视频免费| 亚洲欧美日韩精品久久久| 久久偷窥视频| 欧美在线一区二区三区| 欧美大片免费观看| 久久全球大尺度高清视频| 欧美欧美在线| 欧美 日韩 国产一区二区在线视频 | 亚洲午夜影视影院在线观看| 久久精品国产久精国产一老狼| 夜夜嗨av色一区二区不卡| 久久久精品国产一区二区三区| 一本一道久久综合狠狠老精东影业 | 亚洲视频欧美在线| 久久久久久网| 久久爱www久久做| 国产精品白丝黑袜喷水久久久| 欧美国产免费| 国产自产精品| 午夜精品一区二区三区在线| 亚洲永久在线| 欧美三级午夜理伦三级中文幕| 亚洲国产精品精华液网站| 国产一区二区三区最好精华液 | 久久亚洲图片| 国产欧美 在线欧美| 一区二区三区日韩欧美精品| 亚洲国产天堂久久综合网| 久久精品免费观看| 久久久久久久尹人综合网亚洲| 国产精品久久午夜| 亚洲视频导航| 欧美伊人久久久久久久久影院| 欧美性生交xxxxx久久久| 亚洲免费av电影| 亚洲一区二区三区精品视频| 欧美三区美女| 亚洲一区二区三区乱码aⅴ| 午夜精彩国产免费不卡不顿大片| 欧美日韩国产一区二区三区| 日韩视频在线观看一区二区| 国产精品99久久不卡二区| 欧美系列亚洲系列| 亚洲综合精品一区二区| 久久男女视频| 亚洲久久一区| 国产精品福利在线观看网址| 午夜亚洲精品| 欧美激情一区二区三区成人| 亚洲精品久久久久久久久| 欧美区一区二| 羞羞色国产精品| 老色鬼久久亚洲一区二区 | 国产一区二区三区久久久久久久久 | 亚洲一区在线观看视频 | 亚洲欧美国产制服动漫| 国产日韩在线一区| 久久久久久久网站| 亚洲日本中文字幕| 亚洲欧美日韩在线不卡| 国产欧美精品| 麻豆91精品91久久久的内涵| 亚洲精品少妇30p| 亚洲欧美日韩一区二区在线| 国产综合色产在线精品| 欧美α欧美αv大片| 正在播放欧美视频| 免费成人av资源网| 亚洲网站在线播放| 一区二区三区亚洲| 欧美日韩在线视频首页| 久久精品国产久精国产爱| 亚洲精品一区在线观看香蕉| 久久国产精品久久久久久电车| 亚洲人成网站在线观看播放| 国产精品女人久久久久久| 快播亚洲色图| 亚洲女与黑人做爰| 亚洲精品极品| 裸体丰满少妇做受久久99精品| 99亚洲视频| 亚洲高清视频在线| 国产乱理伦片在线观看夜一区| 欧美777四色影视在线| 午夜宅男欧美| 中文国产一区| 亚洲国产一二三| 快射av在线播放一区| 亚洲欧美大片| 国产精品99久久久久久白浆小说| 亚洲第一在线视频| 国产亚洲午夜高清国产拍精品| 欧美日韩天堂| 欧美韩日一区| 男人天堂欧美日韩| 久久亚洲影音av资源网| 欧美在线黄色| 午夜久久资源| 亚洲欧美日韩视频二区| 中文久久精品| 中文精品视频| 亚洲神马久久| 亚洲一区二区3| 一区二区三区视频在线| 99国产精品国产精品久久| 亚洲人成在线播放网站岛国| 欧美国产日韩一区二区三区| 免费高清在线视频一区·| 久久只精品国产| 久久在线免费观看视频| 久久一日本道色综合久久| 久久亚洲私人国产精品va媚药| 久久精品视频在线观看| 久久精品三级| 久久久久国内| 老司机免费视频一区二区三区| 久久九九国产精品怡红院| 欧美在线看片a免费观看| 性久久久久久久久| 久久久久成人精品| 久久综合色播五月| 欧美激情小视频| 亚洲国产91精品在线观看| 亚洲日本国产| 在线中文字幕一区| 亚洲免费在线精品一区| 欧美中文字幕| 狼人社综合社区| 欧美日韩亚洲一区三区| 国产精品成人播放| 国产视频在线观看一区二区| 精品不卡在线| 99这里只有精品| 欧美一区视频| 欧美寡妇偷汉性猛交| 亚洲美女区一区| 欧美一区二区在线看| 久久综合久久88| 欧美日韩国产一区| 国产一区二区三区免费在线观看 | 国产精品视频内| 精品成人国产| 亚洲永久免费观看| 老司机aⅴ在线精品导航| 亚洲国产一二三| 欧美亚洲在线观看| 欧美另类一区二区三区| 国产精品欧美日韩一区| 亚洲国产精品尤物yw在线观看 | 久久久91精品国产| 免费看精品久久片| 亚洲午夜精品一区二区| 老司机精品导航| 国产欧美日韩91| 99精品国产在热久久| 久久精品国产欧美激情| 亚洲区免费影片| 欧美一级二级三级蜜桃| 欧美日韩午夜精品| 伊人狠狠色j香婷婷综合| 亚洲视频免费观看| 欧美大片18| 欧美在线一二三| 国产精品美女久久久久aⅴ国产馆| 激情亚洲成人| 欧美一区二区三区免费视频| 亚洲欧洲久久| 麻豆精品视频在线| 国内精品美女在线观看| 亚洲一二三四区| 亚洲精品社区| 欧美精品色综合| 亚洲九九九在线观看| 农村妇女精品| 久久一区欧美| 激情欧美一区二区|