歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux管理 >> Linux網絡

深入Linux網絡編程(一):同步IO

1. IO模型

IO分為同步、異步,阻塞、非阻塞,兩兩組合成4種模型。

2. 同步阻塞IO

2.1 阻塞的原因

一個常見的問題是IO對請求沒有准備好:例如調用讀請求的時候可能設備上沒有數據,但是將來可能有;調用寫請求時可能捨妹沒有准備好接收數據,一會兒可能buffer清空就好了。調用過程一般不去理會這些問題,如果程序員僅僅要求在請求返回時工作做好,那麼驅動設備就應該阻塞這個請求的進程,使他陷入睡眠狀態。

2.2 什麼是睡眠

當一個進程處於睡眠態, 意味著它被移除調度隊列,直到這個狀態被改變之前,CPU都不會處理這個進程。有幾個注意事項:

  • 不要在原子上下文中sleep
  • 無法保證精確的睡眠時間
  • 只有在確定其他進程/內核會喚醒自己時,才能睡眠

2.3 同步阻塞IO的編程模型

3. 同步阻塞IO的網絡編程代碼示例

/* A simple server in the internet domain using TCP
   The port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portno;
     socklen_t clilen;
     char buffer[256];
     struct sockaddr_in serv_addr, cli_addr;
     int n;
     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0) 
        error("ERROR opening socket");
     bzero((char *) &serv_addr, sizeof(serv_addr));
     portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0) 
              error("ERROR on binding");
     listen(sockfd,5);
     clilen = sizeof(cli_addr);
     newsockfd = accept(sockfd, 
                 (struct sockaddr *) &cli_addr, 
                 &clilen);
     if (newsockfd < 0) 
          error("ERROR on accept");
     bzero(buffer,256);
     n = read(newsockfd,buffer,255);
     if (n < 0) error("ERROR reading from socket");
     printf("Here is the message: %s\n",buffer);
     n = write(newsockfd,"I got your message",18);
     if (n < 0) error("ERROR writing to socket");
     close(newsockfd);
     close(sockfd);
     return 0; 
}
Copyright © Linux教程網 All Rights Reserved