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:\n"); 
        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\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;
}
  • 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;
}

参考:

  • 5
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

callinglove

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值