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

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 閱讀(585) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲国产视频一区| 国产九区一区在线| 亚洲欧美在线视频观看| 老司机精品久久| 尤物yw午夜国产精品视频| 性欧美超级视频| 在线一区二区视频| 国产精品久久久久秋霞鲁丝| 中文在线一区| 亚洲视频免费看| 一区二区欧美激情| 亚洲欧美成人网| 一区二区三区在线看| 欧美电影电视剧在线观看| 久久综合九色| 男人的天堂亚洲在线| 欧美成人在线免费视频| 日韩视频在线一区二区三区| 亚洲精品资源| 国产精品麻豆va在线播放| 日韩视频免费在线观看| 国产精品一区二区欧美| 亚洲视频免费在线| 亚洲欧美日韩第一区| 久久成人精品一区二区三区| 永久555www成人免费| 久久爱91午夜羞羞| 99riav国产精品| 欧美激情视频网站| 新狼窝色av性久久久久久| 国产精品嫩草影院av蜜臀| 亚洲视频一区二区| 欧美一激情一区二区三区| 国产乱码精品一区二区三区不卡| 亚洲欧美日韩精品久久奇米色影视 | 一区二区三区视频在线看| 国产一区二区高清视频| 欧美电影电视剧在线观看| 91久久精品日日躁夜夜躁国产| 一区二区三区免费网站| 性久久久久久久久久久久| 国产欧美精品在线播放| 亚洲精品视频在线看| 亚洲一二三区在线| 老司机精品视频网站| 亚洲欧洲三级| 伊人一区二区三区久久精品| 欧美aa在线视频| 久久久久九九九九| 欧美日韩国产影片| 另类av一区二区| 欧美日韩国产小视频在线观看| 亚洲色在线视频| 久久久久久久久久久久久久一区 | 国产日韩在线视频| 一本一本久久a久久精品综合妖精| 亚洲先锋成人| 一区二区在线观看av| 欧美久久久久免费| 亚洲第一精品夜夜躁人人爽 | 国产精品亚洲аv天堂网| 亚洲激情二区| 欧美在线观看www| 国产精品黄页免费高清在线观看| 欧美高清视频| 午夜精品久久久| 国产精品豆花视频| 久久综合中文字幕| 亚洲深夜福利在线| 欧美刺激午夜性久久久久久久| 亚洲香蕉网站| 亚洲欧洲在线播放| 国产一级精品aaaaa看| 欧美激情在线观看| 久久久国产精品亚洲一区 | 亚洲欧美日韩在线观看a三区| 影音先锋国产精品| 国产精品色一区二区三区| 欧美福利在线| 亚洲激情在线激情| 久久香蕉国产线看观看av| 狠狠色丁香婷婷综合| 久久久久免费视频| 欧美高清视频在线播放| 久久成人精品| 精品成人在线| 国产女主播一区二区三区| 欧美日韩成人一区二区| 久久综合网hezyo| 欧美一区二区三区视频在线观看 | 欧美电影电视剧在线观看| 性欧美1819sex性高清| 狂野欧美性猛交xxxx巴西| 亚洲欧美在线免费| 亚洲夜间福利| 亚洲蜜桃精久久久久久久| 欧美日韩精品一本二本三本| 欧美成人免费大片| 久久躁日日躁aaaaxxxx| 久久国产精品久久久| 午夜精品视频在线| 午夜国产精品视频免费体验区| 在线亚洲免费视频| 这里只有精品电影| 一区二区三区欧美在线观看| 99精品视频免费| 久久精品国产久精国产爱| 亚洲国产合集| 欧美美女视频| 欧美日韩三区四区| 性欧美大战久久久久久久久| 亚洲综合欧美日韩| 亚洲男人天堂2024| 欧美亚洲色图校园春色| 久久国产精品久久久| 久久久噜噜噜久久| 模特精品在线| 欧美精品国产精品| 欧美精品一卡| 国产精品露脸自拍| 国产午夜亚洲精品不卡| 激情五月综合色婷婷一区二区| 亚洲国产成人在线播放| 亚洲另类春色国产| 亚洲视频在线看| 欧美一区二区在线| 老司机久久99久久精品播放免费 | 一区二区三区你懂的| 亚洲性视频网址| 欧美一区在线视频| 蜜月aⅴ免费一区二区三区| 亚洲影院在线观看| 日韩性生活视频| 亚洲永久精品国产| 久久亚洲综合| 亚洲人成网站在线观看播放| 久久最新视频| 亚洲精品一区二区在线| 亚洲一区二区三区777| 日韩视频专区| 欧美一区二区三区的| 欧美电影在线观看完整版| 国产精品国产亚洲精品看不卡15| 狠狠色综合日日| 一本色道久久综合亚洲二区三区| 亚洲黑丝在线| 亚洲国产精彩中文乱码av在线播放| 亚洲精品一区久久久久久| 欧美在线高清视频| 亚洲国产天堂久久综合| 欧美一级久久| 欧美日韩精品二区| 一区在线观看| 欧美亚洲一级| 亚洲品质自拍| 久久久久久久久伊人| 国产精品久久久久久久久免费樱桃| 一区二区亚洲欧洲国产日韩| 亚洲欧美中文字幕| 亚洲国产色一区| 久久久久久综合| 国产乱码精品一区二区三| 一本久久综合亚洲鲁鲁五月天| 久久全国免费视频| 美女国产精品| 亚洲欧美日韩在线| 欧美日韩一区在线| 亚洲国产欧美另类丝袜| 久久久久久综合| 亚洲一区三区在线观看| 欧美日韩一卡| 亚洲美女毛片| 亚洲电影下载| 久久亚洲精品一区二区| 久久精品免费观看| 国产精品一卡二| 亚洲一区二区三区在线播放| 亚洲欧洲精品成人久久奇米网| 久久免费99精品久久久久久| 国产一区导航| 欧美在线日韩在线| 亚洲伊人网站| 国产精品婷婷午夜在线观看| 亚洲一二三区在线| 99综合在线| 欧美色视频一区| 国产亚洲精品久久飘花| 小处雏高清一区二区三区| 亚洲深夜av| 国产精品区一区二区三| 亚洲欧美视频在线观看| 亚洲视频网站在线观看| 国产精品国产| 欧美主播一区二区三区| 午夜影视日本亚洲欧洲精品| 国产精品久久久亚洲一区| 欧美一级二区| 欧美有码在线视频| 在线观看亚洲精品视频| 99re热这里只有精品视频|