Linux网络编程常见面试题

来源:互联网 发布:淘宝二手交易流程 编辑:程序博客网 时间:2024/05/21 00:48

概述

TCP和UDP是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议。

  • TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流,TCP套接口是字节流套接口(stream socket)的一种。
  • UDP:用户数据报协议。UDP是一种无连接协议。UDP套接口是数据报套接口(datagram socket)的一种。

TCP与UDP简介

基本TCP客户—服务器程序设计基本框架

TCP流程

基本UDP客户—服务器程序设计基本框架

UDP流程

UDP和TCP的对比

  • TCP面向连接(三次握手机制),通信前需要先建立连接;UDP面向无连接,通信前不需要建立连接;
  • TCP保障可靠传输(按序、无差错、不丢失、不重复、超时重发); UDP不保障可靠传输,使用最大努力交付;
  • TCP面向字节流的传输,UDP面向数据报的传输。

TCP优缺点:

  • 优点: 
    1.TCP提供以认可的方式显式地创建和终止连接。 
    2.TCP保证可靠的、顺序的(数据包以发送的顺序接收)以及不会重复的数据传输。 
    3.TCP处理流控制。 
    4.允许数据优先 
    5.如果数据没有传送到,则TCP套接口返回一个出错状态条件。 
    6.TCP通过保持连续并将数据块分成更小的分片来处理大数据块。—无需程序员知道

  • 缺点: TCP在转移数据时必须创建(并保持)一个连接。这个连接给通信进程增加了开销,让它比UDP速度要慢。

UDP优缺点:

1.UDP不要求保持一个连接 
2.UDP没有因接收方认可收到数据包(或者当数据包没有正确抵达而自动重传)而带来的开销。 
3.设计UDP的目的是用于短应用和控制消息 
4.在一个数据包连接一个数据包的基础上,UDP要求的网络带宽比TDP更小。

TCP/IP应用编程接口(API)

  • TCP服务端:
  • TCP客户端:
#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h> #include <sys/socket.h>#include <netinet/in.h>#define PORT  2345#define DSET_IP_ADDRESS "192.168.218.141"int main(int argc, char *argv[]) {    int sockfd;    char buffer[1024];    struct sockaddr_in server_addr;    sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);    if(sockfd == -1) {        perror("socket error");        exit(EXIT_FAILURE);      }     bzero(&server_addr,sizeof(server_addr));    server_addr.sin_family=AF_INET;     server_addr.sin_port=htons(PORT);     server_addr.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);     if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) {           perror("connect error.");        exit(EXIT_FAILURE);    }    do {        printf("Please input char:\n");         fgets(buffer,1024,stdin);        write(sockfd,buffer,strlen(buffer));    } while (strncmp(buffer, "quit", 4) != 0);    close(sockfd);    exit(EXIT_SUCCESS); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • UDP服务端:
 #include<stdio.h>  # include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<unistd.h> #include<errno.h> #include<string.h> #include<stdlib.h> #define SERV_PORT   3000 int main(int argc, char *argv[]){    int sock_fd;   //套接子描述符号    int recv_num;    int send_num;    int client_len;    char recv_buf[20];    struct sockaddr_in  addr_serv;    struct sockaddr_in  addr_client;//服务器和客户端地址    sock_fd = socket(AF_INET,SOCK_DGRAM,0);    if(sock_fd < 0){        perror("socket");        exit(1);    } else {         printf("sock sucessful\n");    }    //初始化服务器断地址    memset(&addr_serv,0,sizeof(struct sockaddr_in));    addr_serv.sin_family = AF_INET;//协议族    addr_serv.sin_port = htons(SERV_PORT);    addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);//任意本地址    client_len = sizeof(struct sockaddr_in);    /*绑定套接子*/    if(bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in))<0 ){        perror("bind");        exit(1);    } else{        printf("bind sucess\n");    }    while(1){        printf("begin recv:\n");        recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len);        if(recv_num <  0){            printf("bad\n");            perror("again recvfrom");            exit(1);        } else{            recv_buf[recv_num]='\0';            printf("recv sucess:%s\n",recv_buf);        }        printf("begin send:\n");        send_num = sendto(sock_fd,recv_buf,recv_num,0,(struct sockaddr *)&addr_client,client_len);        if(send_num < 0){            perror("sendto");            exit(1);        } else{            printf("send sucessful\n");        }    }    close(sock_fd);    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • UDP客户端:
#include<stdio.h>#include<string.h>#include<errno.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#define DEST_PORT 3000#define DSET_IP_ADDRESS  "192.168.1.103"int main(int argc, char *argv[]){    int sock_fd;/*套接字文件描述符*/    int send_num;    int recv_num;    int dest_len;    char send_buf[20]={"hello tiger"};    char recv_buf[20];    struct sockaddr_in addr_serv;/*服务端地址,客户端地址*/    sock_fd = socket(AF_INET,SOCK_DGRAM,0);//创建套接子    //初始化服务器端地址    memset(&addr_serv,0,sizeof(addr_serv));    addr_serv.sin_family = AF_INET;    addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);    addr_serv.sin_port = htons(DEST_PORT);    dest_len = sizeof(struct sockaddr_in);    printf("begin send:\n");    send_num = sendto(sock_fd,send_buf,sizeof(send_buf),0,(struct sockaddr *)&addr_serv,dest_len);    if(send_num < 0){        perror("sendto");        exit(1);    } else{        printf("send sucessful:%s\n",send_buf);    }    recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_serv,&dest_len);    if(recv_num <0 ){        perror("recv_from");        exit(1);    } else{        printf("recv sucessful\n");        recv_buf[recv_num]='\0';        printf("the receive:%s\n",recv_buf);    }    close(sock_fd);    return 0;}
原创粉丝点击