系统与网络编程-(项目前准备)

系统与网络编程

select函数

  • select和pselect多用于I/O操作,他们见识多个文件描述符的集合,判断是否有符合条件的时间发生
  • I/O操作:不是对 外围设备直接进行操作,而是对设备与cpu连接的接口电路的操作。
  • 函数声明: int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
  • numfd:一个整形变量的比(readfds,writefds,exceptfds)中的文件描述符的最大值大1.所以必须计算文件描述符最大值以传入。
  • readfds:这个文件描述符集合用来见识文件描述符集里每个文件是否有文件可读,当select返回时,将清空不可读内容。
  • writefds:这个文件描述符集合用来见识文件描述符集里每个文件是否有文件可写,当select返回时,将清空不可写内容。
    -exceptfds:这个文件描述符集合监视文件描述符集中的每个文件是否发生错误
  • fd_sets
//将一个文件描述符清零
void FD_CLR(int fd, fd_set *set);
//将文件描述符fd加入到集合set中
int  FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);
  • 函数试用
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/select.h>
void setMaxFd(int *pMaxFd,int fd)
{
    if(*pMaxFd<fd)
    {
        *pMaxFd=fd;
    }
}
int main()
{
    int iMaxFd=0;
    fd_set readSet;
    int ret=0;
    #if 0
    FD_ZERO(&readSet);//清空
    FD_SET(STDIN_FILENO,&readSet);//将SRDIN_FILENO写入集合readSet中
    //判断文件描述符集合中是否包含了某个文件描述符
    //若包含了返回1,不包含返回0
    int ret=FD_ISSET(TDIN_FILENO,&readSet);
    printf("ret=%d\n",ret);
    #endif
//  ret=FD_ISSET(STDOUT_FILENO,&readSet);
//  printf("ret=%d\n",ret);
    char caBuf[32]={'\0'};
    while(1)
    {   //select()将会阻塞,直到指定的文件描述符集合中有文件符合相应的I/O操作
        FD_ZERO(&readSet);
        FD_SET(STDIN_FILENO,&readSet);//将SRDIN_FILENO写入集合readSet中
        setMaxFd(&iMaxFd,STDIN_FILENO);
        ret=select(iMaxFd+1,&readSet,NULL,NULL,NULL);
        if(ret==-1)
        {
            perror("select");
            return -1;
        }
        //若函数成功返回,那么文件描述符集合中只会包含将要进行IO操作的文件描述符
        //其他没有要进行I/O操作的文件描述符会被清空.
        //如果需要重新监控,需要将清除掉的问津描述符重新添加到集合中.
        //推荐做法:将集合清空,将所有需要监控的文件描述符都添加一遍
        if(FD_ISSET((STDIN_FILENO),&readSet))
        {
            memset(caBuf,'\0',sizeof(caBuf));
            read(STDIN_FILENO,caBuf,sizeof(caBuf));
            printf("%s\n",caBuf);
        }
    }
    printf("Hello World\n");
    return 0;
}
Paste_Image.png
  • 地址Address already in use 解决方法:
Paste_Image.png
  • UDP试用
    • server端
    #include<sys/types.h>
    #include<sys/socket.h>
    #include <sys/wait.h>
    #include<stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <netdb.h>
    #include<string.h>
    #include<netinet/in.h>//struct sockaddr_in
    #define MYPORT 5000
    int main(int argc,char *argv[])
    {
        int sockfd=-1;
        struct sockaddr_in clientAddr;//用来存储服务器端套接字地址
        struct hostent *he;
        int numbytes;
        if(argc!=3)
        {
            /*检测是否有所需参数,如没有,则使用显示方法后退出*/
            fprintf(stderr,"usage:talker hostname message\n");
            return 1;
        }
        if((he=gethostbyname(argv[1]))==NULL)
        {
            /*取得主机信息,如果显示失败则显示错误信息后退出*/
            herror("gethostbyname");
            return 1;
        }
        sockfd=socket(AF_INET,SOCK_STREAM,0);//使用IPv4基于链接的通信
        if(sockfd==-1)
        {
            perror("socket");
            return -1;
        }
        //用结构体来保存服务器的端口和IP地址
        clientAddr.sin_family=AF_INET;//使用IPv4(Internet地址族)主机字节顺序
        clientAddr.sin_port=htons(MYPORT);//端口号(窗口)将主机字节顺序转换为网络字节顺序
        clientAddr.sin_addr=*((struct in_addr*)he->h_addr);
        bzero(&(clientAddr.sin_zero),8);//添0将整个结构剩余部分数据设为0
        int ret;
        if((numbytes=sendto(sockfd,argv[2],strlen(argv[2]),0,
            (struct sockaddr *)&clientAddr,sizeof(struct sockaddr)))==-1)
        {
            /*将信息发送到指定的主机指定端口,如出错则退出*/
            perror("recvfrom");
            return -1;
        }
        printf("send %d bytes to %s\n",numbytes,
                inet_ntoa(clientAddr.sin_addr));
        /*关闭套接字描述符退出*/
        close(sockfd);
        return 0;
    }
    
    • client端
    #include<sys/types.h>
    #include <sys/wait.h>
    #include<sys/socket.h>
    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    #include <errno.h>
    #include<netinet/in.h>//struct sockaddr_in
    
    #define MYPORT 5000
    #define MAXBUFLEN 100
    int main(void)
    {
        int sockfd = -1;    
        struct sockaddr_in serverAddr;      //本机的地址信息
        struct sockaddr_in clientAddr;      //连接的客户地址信息
    
        int addr_len,numbytes;
        char buf[MAXBUFLEN];
        //创建socket描述符,用于监听接受客户端的连接
        //AF_INET:ipv4
        //SOCK_STREAM:tcp协议
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);    //取得一套接字描述符
        if (-1 == sockfd)
        {
            perror("socket");           //失败则给出失败信息
            return -1;
        }
    
        serverAddr.sin_family = AF_INET;    //主机字节顺序
        serverAddr.sin_port = htons(8888);  //网络字节顺序
        serverAddr.sin_addr.s_addr = inet_addr("192.168.16.95");//自动设置为自己的ip
        bzero(&(serverAddr.sin_zero), 8);       //将剩余空间清零
        
        //将sockfd端口和地址进行绑定  
        int ret = -1;
        ret = bind(sockfd, (struct sockaddr *)&serverAddr
                       , sizeof(serverAddr));
        if (-1 == ret)
        {
            perror("bind");
            return -1;
        }
        addr_len=sizeof(struct sockaddr);
        /*接收数据*/
        numbytes=recvfrom(sockfd,buf,MAXBUFLEN,0,(struct sockaddr *)&serverAddr,&addr_len);
        if(numbytes==-1)
        {
            perror("recvfrom");
            return -1;
        }
        /*显示接受到的数据*/
        printf("got packet from%s\n",inet_ntoa(serverAddr.sin_addr));
        printf("packet is %d bytes long\n",numbytes);
        buf[numbytes]='\0';
        printf("packet contains %s\n",buf);
        /*关闭套接字连接*/
        close(sockfd);
        return 0;
    }
    
  • 简单的文件传输
    • client
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #define    MAXLINE        1024
    
    void usage(char *command)
    {
        printf("usage :%s ipaddr portnum filename\n", command);
        exit(0);
    }
    int main(int argc,char **argv)
    {
        struct sockaddr_in    serv_addr;
        char                  buf[MAXLINE];
        int                    sock_id;
        int                    read_len;
        int                    send_len;
        FILE                  *fp;
        int                    i_ret;
      
        if (argc != 4) {
            usage(argv[0]);
        }
        
        /* open the file to be transported commented by guoqingbo*/
        if ((fp = fopen(argv[3],"r")) == NULL) {
            perror("Open file failed\n");
            exit(0);
        }
        
        /* create the socket commented by guoqingbo*/
        if ((sock_id = socket(AF_INET,SOCK_STREAM,0)) < 0) {
            perror("Create socket failed\n");
            exit(0);
        }
        
        memset(&serv_addr, 0, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(atoi(argv[2]));
        inet_pton(AF_INET, argv[1], &serv_addr.sin_addr);
      
        /* connect the server commented by guoqingbo*/
        i_ret = connect(sock_id, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr));
        if (-1 == i_ret) {
            printf("Connect socket failed\n");
            printf("======\n");
          return -1;
        }
        
        /* transported the file commented by guoqingbo*/
        bzero(buf, MAXLINE);
        while ((read_len = fread(buf, sizeof(char), MAXLINE, fp)) >0 ) {
            send_len = send(sock_id, buf, read_len, 0);
            if ( send_len < 0 ) {
                perror("Send file failed\n");
                exit(0);
            }
            bzero(buf, MAXLINE);
        }
    
        fclose(fp);
        close(sock_id);
        printf("Send Finish\n");
        return 0;
    }
    
    • server端
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #define    MAXLINE        1024
    
    void usage(char *command)
    {
        printf("usage :%s portnum filename\n", command);
        exit(0);
    }
    int main(int argc,char **argv) 
    {
        struct sockaddr_in    serv_addr;
        struct sockaddr_in    clie_addr;
        char                  buf[MAXLINE];
        int                    sock_id;
        int                    link_id;
        int                    recv_len;
        int                    write_leng;
        int                    clie_addr_len;
        FILE                  *fp;
    
        if (argc != 3) {
            usage(argv[0]);
        }
        if ((fp = fopen(argv[2], "w")) == NULL) {
            perror("Open file failed\n");
            exit(0);
        }
        if ((sock_id = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
            perror("Create socket failed\n");
            exit(0);
        }
        /*fill the server sockaddr_in struct commented by guoqingbo*/
        memset(&serv_addr, 0, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(atoi(argv[1]));
        serv_addr.sin_addr.s_addr = inet_addr("192.168.16.95");
    
        if (bind(sock_id, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0 ) {
            perror("Bind socket failed\n");
            exit(0);
        }
    
        if (-1 == listen(sock_id, 10)) {
            perror("Listen socket failed\n");
            exit(0);
        }
        /* server part commented by guoqingbo*/
        while (1) {
            clie_addr_len = sizeof(clie_addr);
            link_id = accept(sock_id, (struct sockaddr *)&clie_addr, &clie_addr_len);
            if (-1 == link_id) {
                perror("Accept socket failed\n");
                exit(0);
            }
            bzero(buf, MAXLINE);
            while (recv_len = recv(link_id, buf, MAXLINE, 0)) {
                /* receiver data part commented by guoqingbo*/
                if(recv_len < 0) {
                    printf("Recieve Data From Server Failed!\n");
                    break;
                }
                printf("#");
                write_leng = fwrite(buf, sizeof(char), recv_len, fp);
                if (write_leng < recv_len) {
                    printf("Write file failed\n");
                    break;
                }
                bzero(buf,MAXLINE);
            }
            printf("\nFinish Recieve\n");
            fclose(fp);
            close(link_id);
        }
        close(sock_id); 
        return 0;
    }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容