美文网首页
网络编程基础

网络编程基础

作者: loveforkeeps | 来源:发表于2016-01-07 12:03 被阅读96次
    • 进程的网络地址:

      进程是出于运行过程中的程序实例,是操作系统调度和分配的基本单位。每个进程至少拥有一个线程否则,系统会自动撤销该进程和它的地址空间。

    • 三种套接字:

      • 数据报套接字:无连接,不保证可靠,独立的数据传输服务。
      • 流式套接字:提供双向、有序、无重复、无边界记录、可靠的数据传输服务。需要事先建立连接。
      > 面向连接的协议和面向无连接的区别在明白了这个之后变得很清楚。
      
      • 原始套接字:允许直接访问较低层的协议(如IP,ICMP)用与检验新的协议的实现。
    • 网络协议的特征:

    1. 面向消息的协议与基于流的协议:
      • 面向消息的协议:以消息为单位在网上传输数据。一条一条的发送与接收。每条消息间都是独立的,存在着消息边界。
      • 基于流的协议: 不保护消息的边界,将数据拆封成字节流连续的传输,不管实际消息边界是否存在,TCP就是基于流的协议。
    2. 面向连接和无连接的服务:
      • 面向连接:每一次完整的传输数据都要建立连接。在数据传输中,各数据分组不携带目的地址,而是使用连接号。本质上讲,连接是一个管道。通信前通过握手,相互传送连接信息,一方面确定了通行的路径,另一方面还可以相互协商,做好通信的准备,例如:准备收发的缓冲区。
      • 面向无连接:类似邮政系统服务的抽象。每个分组都携带完整的目的地址,各分组在系统中独立传送。无法保证分组先后到达的顺序,不进行分组的恢复与重传,不保证传输的可靠性。UDP就是无连接的协议。
      • 可靠性和次序性:
        可靠性:可靠性保证了发送端发送的每一个字节都达到既定的接受端,保证数据的完整性。
        次序性:保证收到的数据的顺序就是发送端发送的顺序。
    • P2P(对等网、点对点)

      • P2P技术:在计算机直接直接进行资源和服务共享。
      • 特征:
        1. 分散性:分布式系统
        2. 规模性:
        3. 扩展性:随时加入
        4. Servent性(sever&client)
        5. 自治性:自行加入与退出
        6. 互助性
        7. 自组织性:自行组织不需要任何管理员
    • Internet中网间进程的标识

      • 用一个三元组可以在全局中唯一的标识一个应用层进程:
        1. 传输层协议
        2. 主机的IP地址
        3. 传输层的端口号

    Winsock下文件传输:

    文件传输
    1, 注册套接字函数socket(int af,int type,int protocol)
    参数解释:
    af : 一个地址描述 ,目前只支持AF_INET格式,也就是说在本次实验中此参数直接写
    为AF_INET即可。
    type: 指定socket类型,例如 TCP类型(SOCK_STREAM) UDP类型(SOCK_DGRAM)

    protocol: 套接口制订协议类型 可以为0,。 常用类型有 IPPROTO_TCP 、IPPROTO_UDP等

    2, 绑定套接字函数 bind ( SOCKET s , const struct sockaddr FAR *addr , int namelen );
    参数解释:
    s :socket()函数返回的套接口描述字
    addr : 指向Socket地址的指针
    namelen :该地址的长度

    3,监听函数listen(SOCKET s,int backlog)
    参数解释:
    s: socket()函数返回的套接口描述字

    backlog:等待连接队列的最大长度

    4,接收连接函数accept(SOCKET s,struct sockaddr FAR* addr,int FAR* addrlen)
    参数解释:
    s: socket()函数返回的套接口描述字

    addr:(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。addr参数的实际格式由套接口创建时所产生的地址族确定

    addrlen:(可选)指针,输入参数,配合addr一起使用,指向存有addr地址长度的整型数

    5, 发送连接请求函数connect(SOCKET s,const struct coskaddr FAR* name,int namelen)
    参数解释:
    s: socket()函数返回的套接口描述字

    name: 想要进行连接的端口名

    namelen: 名字长度

    6,发送数据函数send( SOCKET s, const char FAR* buf, int len, int flags)
    接收文件函数recv(SOCKET s, char FAR* buf, int len, int flags)
    参数解释:
    s:socket()函数返回的套接口描述字
    buf:用于接收数据的缓冲区
    len:缓冲区长度
    flags:指定调用方式
    7,文件操作函数fopen(const char * path,const char * mode) fclose(FILE* stream)
    参数解释:

    path:欲打开的文件路径及文件名

    mode:代表流形态

    stream:文件流指针

    客户端
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <WinSock2.h>
    #include <ws2tcpip.h>
    #pragma comment(lib,"ws2_32.lib")

      #define MAXLINE 1024
      #define SEVERPORT 1026
      #define SEVERPORTADDR "192.168.1.110"
    
      int main () 
      {
    WSADATA wsaData;//wsdate 用于存储调用windock中socket初始化函数返回的初始化信息 
    WORD socketVersion = MAKEWORD(2.2); //就是一个word地位用来指明主版本号,高位用来指明修正号
    //初始化windows socket
    if (0 != WSAStratup(socketVersion,&wsaData)) {
        printf("初始化失败!\n");
        exit(0);
    }
    char recvbuff[MAXLINE + 1]; //创建缓冲区
    int sockfd,n;//socket标志字,那么fd是什么意思呢,fd是file descriptor的缩写。顾名思义就是文件描述符啦。
    //设置地址
    struct sockaddr_in servaddr;
    //给地址初始化
    memset(&servaddr,0,sizeof(servaddr));
    //设置使用IPV4通信
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SEVERPORT);//host to network short int;
    //sin_addr中的联合S_un包含的s_un.s_addr 意思为An IPv4 address formatted as a u_long
    servaddr.sin_addr.S_un.S_addr = inet_addr(SEVERPORTADDR);
    //生成套接字
    if ((sockfd  = socket(AF_INET,SOCK_STREAM.0)) < 0) {
        printf("sockfd error!\n");
        exit(0);
    }
    
    //尝试连接服务器
    printf("请输入要传输的文件\n");
    
    char filename[256];
    scanf("%s",filename);
    
    //建立文件缓冲区,定义文件指针,指向传输文件
    FILE * fp = (FILE *)NULL;//初始化文件指针
    
    fp = fopen(filename,"rb"); //用二进制格式打开一个文件,只允许读。
    
    
    if (fp == (FILE *)NULL) {
        printf("打开文件失败!\n");
        return 0;
    }
    
    //发送文件名
    n = send(sockfd, filename, strlen(filename), 0);
    //如果无错误,返回值为发送数据的总数
    printf("发送数据为:%d\n",n);
    
    //接受服务器返回的信息
     n = recv(sockfd,recvbuff,MAXLINE,0);
     
    if(strcmp(recvbuff,  "ok") == 0){//如果服务器返回ok则开始传送文件
        memset(recvbuff, 0, sizeof(recvbuff));
        while(!feof(fp)){
            n = fread(recvbuff, sizeof(char), 1000, fp);
            printf("%d\n", n);
            n = send(sockfd, recvbuff, n, 0);
            printf("send n = %d\n", n);
        }//传送文件
        fclose(fp);//关闭文件
    }
    closesocket(sockfd);
    //关闭网络描述符
    return 0;
      }
    

    服务器
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<WinSock2.h>

      #define PORTNUMBER 3333 //定义端口号
      #define MAXLINE           1024 //缓存大小
      #pragma comment(lib,"ws2_32.lib")
    
      #define QueueLen 1
    
      char buffer[MAXLINE+1];
      int n;
      int  main(int argc, char * argv[])
      {
    WORD version;
    version = MAKEWORD(1, 1);
    WSADATA wsa;
    if(0 != WSAStartup(version, &wsa)){ 
                printf("WSAStartup error!\n");
              exit(0);
          }//初始化 socket
    
    struct sockaddr_in servaddr; //服务器IP地址
    struct sockaddr_in clientaddr;//客户端IP地址
    int listenfd;//监听的网络描述符
    int clientfd;//客户端网络描述符
    int alen;
    
    memset(&servaddr, 0, sizeof(servaddr)); //初始化
    
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY; //INADDR_ANY 你网卡上的任意IP,比如你有多个IP
    servaddr.sin_port = htons((unsigned short) PORTNUMBER); 
    //初始化服务器
    
    listenfd =  socket(AF_INET, SOCK_STREAM, IPPROTO_IP ); 
    //初始化监听的网络描述符
    if(listenfd< 0){
        fprintf(stderr, "socket createion failed!\n");
        exit(0);
    }//失败
    if(bind(listenfd, (struct  sockaddr *) &servaddr, sizeof(servaddr)) < 0){
        fprintf(stderr, "bind failed!\n");
        exit(0);
    }//版定到端口
    if(listen(listenfd, QueueLen) < 0){
        fprintf(stderr, "listen failed!\n");
        exit(0);
    }//绑定失败
    char filename[256];
    while(1){
        alen = sizeof(clientaddr);
        if((clientfd = accept(listenfd, (struct sockaddr*)&clientaddr, &alen)) < 0){
            fprintf(stderr, "accept failed!\n");
            exit(0);
        }//接受客户端的连接
        n = recv(clientfd, filename, 255, 0);//接受客户端发送的信息
        filename[n] = '\0';
        printf("recv n = %d\n", n);
        FILE * fp = (FILE *)NULL;
        if((FILE *) NULL == (fp = fopen(filename, "wb"))){
            printf("open file %s failed!\n", filename);
            return 0;
        }
        n = send(clientfd, "ok", strlen("ok"), 0);
        //发送 ok 到客户端,让客户端开始发送文件
        printf("send n = %d\n", n);
        while(n = recv(clientfd, buffer, 1000, 0)){
            printf("recv n = %d\n", n);
            fwrite(buffer, sizeof(char), n, fp);
            if(n != 1000)
                break;
        }//接受文件并保存
        fclose(fp);
        closesocket(clientfd);
        //关闭文件,关闭网络描述符
    }
    return 0;
     }

    相关文章

      网友评论

          本文标题:网络编程基础

          本文链接:https://www.haomeiwen.com/subject/dnpkhttx.html