• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • Linux網絡編程基礎(一)

    發表于:2007-05-25來源:作者:點擊數: 標簽:網絡linux初等網絡編程基礎
    初等網絡函數介紹(TCP)及示例程序 1、 socket int socket(int domain, int type,int protocol) domain:說明我們網絡程序所在的主機采用的通訊協族(AF_ UNIX 和AF_INET等). AF_UNIX只能夠用于單一的 Unix 系統進程間通信,而AF_INET是針對Inte .net 的,因而可

    初等網絡函數介紹(TCP)及示例程序

    1、socket
        int socket(int domain, int type,int protocol)

        domain:說明我們網絡程序所在的主機采用的通訊協族(AF_UNIX和AF_INET等). AF_UNIX只能夠用于單一的Unix系統進程間通信,而AF_INET是針對Inte.net的,因而可以允許在遠程 主機之間通信(當我們 man socket時發現 domain可選項是 PF_*而不是AF_*,因為glibc是posix的實現 所以用PF代替了AF,不過我們都可以使用的).

        type:我們網絡程序所采用的通訊協議(SOCK_STREAM,SOCK_DGRAM等) SOCK_STREAM表明我們用的是TCP協議,這樣會提供按順序的,可靠,雙向,面向連接的比特流. SOCK_DGRAM 表明我們用的是UDP協議,這樣只會提供定長的,不可靠,無連接的通信.

        protocol:由于我們指定了type,所以這個地方我們一般只要用0來代替就可以了 socket為網絡通訊做基本的準備.成功時返回文件描述符,失敗時返回-1,看errno可知道出錯的詳細情況

    2、bind
        int bind(int sockfd, struct sockaddr *my_addr, int addrlen)

        sockfd:是由socket調用返回的文件描述符.

        addrlen:是sockaddr結構的長度.

        my_addr:是一個指向sockaddr的指針. 在中有 sockaddr的定義

        struct sockaddr{
          unisgned short as_family;
          char sa_data[14];
        };

        不過由于系統的兼容性,我們一般不用這個頭文件,而使用另外一個結構(struct sockaddr_in) 來代替.在中有sockaddr_in的定義
        struct sockaddr_in{
          unsigned short sin_family;
          unsigned short int sin_port;
          struct in_addr sin_addr;
          unsigned char sin_zero[8];

        我們主要使用Internet所以sin_family一般為AF_INET,sin_addr設置為INADDR_ANY表示可以 和任何的主機通信,sin_port是我們要監聽的端口號.sin_zero[8]是用來填充的. bind將本地的端口同socket返回的文件描述符捆綁在一起.成功是返回0,失敗的情況和socket一樣

    3、listen
        int listen(int sockfd,int backlog)

        sockfd:是bind后的文件描述符.

        backlog:設置請求排隊的最大長度.當有多個客戶端程序和服務端相連時, 使用這個表示可以介紹的排隊長度. listen函數將bind的文件描述符變為監聽套接字.返回的情況和bind一樣.

    4、aclearcase/" target="_blank" >ccept
        int accept(int sockfd, struct sockaddr *addr,int *addrlen)

        sockfd:是listen后的文件描述符.  

        addr,addrlen是用來給客戶端的程序填寫的,服務器端只要傳遞指針就可以了. bind,listen和accept是服務器端用的函數,accept調用時,服務器端的程序會一直阻塞到有一個 客戶程序發出了連接. accept成功時返回最后的服務器端的文件描述符,這個時候服務器端可以向該描述符寫信息了. 失敗時返回-1.

    5、connect
        int connect(int sockfd, struct sockaddr * serv_addr,int addrlen)

        sockfd:socket返回的文件描述符.

        serv_addr:儲存了服務器端的連接信息.其中sin_add是服務端的地址

        addrlen:serv_addr的長度

        connect函數是客戶端用來同服務端連接的.成功時返回0,sockfd是同服務端通訊的文件描述符 失敗時返回-1.

    6、程序示例:

    /******* 服務器程序 (server.c) ************/
    #include "stdio.h"
    #include "stdlib.h"
    #include "errno.h"
    #include "sys/types.h"
    #include "sys/socket.h"
    #include "unistd.h"
    #include "netinet/in.h"
    #include "netdb.h"

    int main(int argc,char *argv[])
    {
            int sockfd,new_fd;
            struct sockaddr_in server_addr;
            struct sockaddr_in client_addr;
            int sin_size,portnumber;
            char hello[]="Hello! Are You Fine?\n";

            if ( argc!=2 )  {
                    fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);
                    exit(1);
            }

            if((portnumber=atoi(argv[1]))<0)  {
                    fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);
                    exit(1);
            }


            /* 服務器端開始建立socket描述符 */
            if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)  {
                    fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
                    exit(1);
            }

            /* 服務器端填充 sockaddr結構 */
            bzero(&server_addr,sizeof(struct sockaddr_in)); 
            server_addr.sin_family=AF_INET;
            server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
            server_addr.sin_port=htons(portnumber);

            /* 捆綁sockfd描述符 */
            if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)  {
                    fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
                    exit(1);
            }

            /* 監聽sockfd描述符 */
            if(listen(sockfd,5)==-1)  {
                    fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
                    exit(1);
            }

            while(1)  {
                    /* 服務器阻塞,直到客戶程序建立連接 */
                    sin_size=sizeof(struct sockaddr_in);
                    if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)  {
                            fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
                            exit(1);
                    }
                    fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr));
                    if(write(new_fd,hello,strlen(hello))==-1)  {
                            fprintf(stderr,"Write Error:%s\n",strerror(errno));
                            exit(1);
                    }
                    close(new_fd);
            }
            close(sockfd);
            exit(0);
    }

    /*******客戶端程序 client.c*********/
    #include "stdio.h"
    #include "stdlib.h"
    #include "errno.h"
    #include "sys/types.h"
    #include "sys/socket.h"
    #include "unistd.h"
    #include "netinet/in.h"
    #include "netdb.h"

    int main(int argc, char *argv[])
    {
            int sockfd;
            char buffer[1024];
            struct sockaddr_in server_addr;
            struct hostent *host;
            int portnumber,nbytes;

            if(argc!=3) {
                    fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
                    exit(1);
            }

            if((host=gethostbyname(argv[1]))==NULL) {
                    fprintf(stderr,"Gethostname error\n");
                    exit(1);
            }

            if((portnumber=atoi(argv[2]))<0) {
                    fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
                    exit(1);
            }

            /*客戶程序開始建立 sockfd描述符*/
            if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) {
                    fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));
                    exit(1);
            }

            /*客戶程序填充服務端的資料*/
            bzero(&server_addr,sizeof(server_addr));
            server_addr.sin_family=AF_INET;
            server_addr.sin_port=htons(portnumber);
            server_addr.sin_addr=*((struct in_addr *)host->h_addr);

            /*客戶程序發起連接請求*/
            if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) {
                    fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
                    exit(1);
            }

            if((nbytes=read(sockfd,buffer,1024))==-1) {
                    fprintf(stderr,"Read Error:%s\n",strerror(errno));
                    exit(1);
            }
            buffer[nbytes]='';
            printf("I have received:%s\n",buffer);
            close(sockfd);
            exit(0);
    }

    編譯產生兩個程序server.o(服務器端)和client.o(客戶端) 先運行./server.o portnumber& (portnumber隨便取一個大于1204且不在/etc/services中出現的號碼 就用8888好了),然后運行 ./client.o localhost 8888 看看有什么結果.

    7、總結
    總的來說網絡程序是由兩個部分組成的--客戶端和服務器端.它們的建立步驟一般是:

    服務器端
    socket-->bind-->listen-->accept

    客戶端
    socket-->connect

    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>