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

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>
            亚洲免费大片| 日韩亚洲欧美一区二区三区| 久久综合给合| 久久久久网址| 麻豆精品一区二区综合av| 看片网站欧美日韩| 欧美精品 国产精品| 欧美日韩理论| 国产日韩一区| 亚洲第一偷拍| 亚洲一区在线播放| 久久精品国产99精品国产亚洲性色| 久久精品成人| 亚洲国产成人精品女人久久久| 国产精品扒开腿做爽爽爽软件| 欧美日韩在线三区| 国内精品**久久毛片app| 亚洲国产你懂的| 亚洲一区二区黄| 老司机精品视频网站| 亚洲激情精品| 欧美一二三区在线观看| 欧美精品福利在线| 国产一区高清视频| 在线一区二区三区四区五区| 欧美中文日韩| 亚洲狼人综合| 巨胸喷奶水www久久久免费动漫| 欧美日韩国产va另类| 国产亚洲一区精品| 国产精品99久久久久久久久| 久久伊人一区二区| 亚洲丝袜av一区| 欧美成人黄色小视频| 国产亚洲一区在线播放| 亚洲一区免费视频| 亚洲国产精品久久久久婷婷老年 | 国产精品99久久不卡二区| 久久久免费精品视频| 国产精品综合网站| 一区二区三区黄色| 欧美国产国产综合| 久久精品国产v日韩v亚洲| 国产精品乱码| 亚洲一区在线观看视频 | 欧美激情国产日韩精品一区18| 国产精品丝袜xxxxxxx| 9国产精品视频| 欧美激情亚洲另类| 久久一区二区三区av| 国产日韩久久| 欧美在线视频导航| 亚洲欧美日韩精品久久久| 欧美日韩在线播放三区四区| 亚洲精品在线电影| 91久久国产综合久久91精品网站| 久久久久网站| 亚洲国产一二三| 亚洲第一页自拍| 欧美二区在线观看| 亚洲麻豆av| 91久久久亚洲精品| 欧美日韩高清在线一区| 亚洲精品乱码久久久久久久久| 欧美成人伊人久久综合网| 久久夜色精品一区| 亚洲乱码精品一二三四区日韩在线| 美女主播精品视频一二三四| 媚黑女一区二区| 久久精品91久久香蕉加勒比| 国内外成人免费激情在线视频网站| 久久精品欧洲| 久久综合九色综合网站| 91久久久一线二线三线品牌| 亚洲高清激情| 欧美色图一区二区三区| 欧美在线视频二区| 久久资源在线| 亚洲午夜精品一区二区三区他趣| 在线一区免费观看| 国产午夜精品一区理论片飘花 | 国产精品日韩专区| 久久精品女人| 欧美精品三级| 欧美一级专区免费大片| 久久精品国产在热久久| 亚洲国产日韩欧美在线99| 亚洲电影下载| 欧美日韩午夜| 久久精品一区二区三区四区| 久久久噜噜噜久久人人看| 亚洲激情国产| 亚洲综合99| 亚洲人成毛片在线播放| 亚洲一区在线播放| 久久久久久一区二区| 中国成人亚色综合网站| 欧美激情亚洲综合一区| 亚洲欧美精品在线观看| 久久久精品五月天| 亚洲一区二区三区中文字幕| 久久久精品免费视频| 亚洲一区二区影院| 免费毛片一区二区三区久久久| 国产精品99久久久久久宅男| 久久精品国产欧美亚洲人人爽| 亚洲精品乱码久久久久久按摩观| 亚洲视频你懂的| 亚洲精品看片| 久久久夜精品| 久久精品亚洲精品| 欧美日韩综合视频| 亚洲成色精品| 一区二区视频在线观看| 亚洲一区二区三区四区视频| 亚洲欧洲日产国产网站| 久久精品水蜜桃av综合天堂| 小辣椒精品导航| 欧美日韩一区二区高清| 亚洲电影欧美电影有声小说| 在线观看日韩精品| 久久激情视频| 久久午夜精品| 国产主播一区| 欧美伊人久久久久久午夜久久久久 | 夜夜嗨一区二区三区| 一色屋精品视频在线观看网站| 一本色道久久综合一区| 亚洲精品乱码久久久久久| 久久综合九色九九| 久久深夜福利| 黄色亚洲在线| 久久久久www| 免费av成人在线| 国产原创一区二区| 欧美一级黄色网| 亚洲欧美制服另类日韩| 国产精品伦一区| 亚洲综合欧美| 久久xxxx精品视频| 国产亚洲亚洲| 久久精品亚洲一区| 欧美成人一区二免费视频软件| 一区二区三区在线免费播放| 久久久精品一品道一区| 免费日韩av| 亚洲精品视频免费观看| 欧美极品一区二区三区| 一区二区三区www| 先锋影音久久| 激情成人中文字幕| 免费观看一区| a4yy欧美一区二区三区| 午夜视频在线观看一区二区| 欧美日韩中文| 欧美自拍丝袜亚洲| 欧美成年人视频| 亚洲视频导航| 国产在线欧美日韩| 欧美成人小视频| 亚洲图片欧洲图片av| 久久精品一区二区三区四区 | 亚洲免费成人| 国产精品久久久999| 久久久www成人免费毛片麻豆| 欧美激情亚洲自拍| 亚洲综合色婷婷| 亚洲高清在线观看一区| 欧美日韩国产天堂| 欧美亚洲综合在线| 亚洲国产欧美不卡在线观看| 亚洲一区二区三区高清不卡| 国产日韩欧美在线播放| 欧美成人精品高清在线播放| 在线视频一区二区| 欧美国产成人精品| 欧美主播一区二区三区| 91久久精品网| 国产一区二区三区高清| 欧美人与禽猛交乱配| 久久精品国产精品亚洲| 亚洲精品国久久99热| 久久九九热re6这里有精品| 99精品国产99久久久久久福利| 国产精品久久久久一区| 美女精品视频一区| 香蕉亚洲视频| 一区二区三区免费看| 欧美成年人网站| 久久国产视频网站| 亚洲视频综合| 亚洲国产精品热久久| 国产欧美一区二区三区在线老狼| 欧美成人精品| 久久久久久久波多野高潮日日 | 亚洲免费在线视频一区 二区| 狼人社综合社区| 亚洲欧美日韩中文在线制服| 日韩性生活视频| 亚洲日本成人女熟在线观看|