Linux网络编程常见面试题

概述

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:
    

    ");
    fgets(buffer,1024,stdin);
    write(sockfd,buffer,strlen(buffer));

    } while (strncmp(buffer, "quit", 4) != 0);
    
    close(sockfd);
    
    exit(EXIT_SUCCESS); 
    

    }

  • 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
    

    ");
    }

    //初始化服务器断地址
    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
    

    ");
    }

    while(1){
        printf("begin recv:
    

    ");
    recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len);
    if(recv_num < 0){
    printf("bad
    ");
    perror(“again recvfrom”);
    exit(1);
    } else{
    recv_buf[recv_num]=‘’;
    printf("recv sucess:%s
    ",recv_buf);
    }
    printf("begin send:
    ");
    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
    ");
    }
    }
    close(sock_fd);

    return 0;
    

    }

  • 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:
    

    ");
    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
    ",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
    

    ");
    recv_buf[recv_num]=‘’;
    printf("the receive:%s
    ",recv_buf);
    }

    close(sock_fd);
    
    return 0;
    

    }

参考:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值