20211320LDK《Unix/Linux系统编程第十三章》学习笔记

本文详细介绍了TCP/IP协议的基础知识,包括其四层结构、IP地址分类和套接字API的应用,以及通过C语言实现的简单网络编程示例,如服务器监听和加密通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

知识点总结

一、TCP/IP协议

TCP/IP是互联网的基础,TCP代表传输控制协议,IP代表互联网协议。目前有IPv4(32位地址)和IPv6(128位地址),目前IPv4使用最多 。TCP/IP的四层结构如下:

层级功能组件
应用层向用户提供应用程序,如电子邮件、文件传输访问、远程登录等ssh, ping
传输层提供应用程序间的通信,格式化信息流,提供可靠传输TCP, UDP
网络层进行网络连接的建立和终止及IP地址的寻找最佳途径等IP
网络接口层传输数据的物理媒介Ethernet

在这里插入图片描述

2. IP主机和IP地址

主机是支持TCP/IP 协议的计算机或设备。每个主机由一个32位的IP地址来标识。为了方便起见,32位的P地址号通常用点记法表示,例如:134.121.64.1,其中各个字节用点号分开。主机也可以用主机名来表示,如dns1.eec.wsu.edu。IP地址分为两部分,即 NetworkID字段和HostID字段。根据划分,IP地址分为A~E类。例如,一个B类P地址被划分为一个16位NetworkID,其中前2位是10,然后是一个16位的HostID字段。发往P地址的数据包首先被发送到具有相同networkID 的路由器。路由器将通过HostID将数据包转发到网络中的特定主机。每个主机都有一个本地主机名localhost,默认P地址为127.0.0.1。本地主机的链路层是一个回送虚拟设备,它将每个数据包路由回同一个 localhost。

套接字API

在网络编程中,TCP/IP的用户界面是通过一系列C语言库函数和系统调用来实现的,这些函数和系统调用统称为套接字API((Rago1993;Stevens等2004)。为了使用套接字 API,我们需要套接字地址结构,它用于标识服务器和客户机。netdbh和sys/socketh中有套接字地址结构的定义。

struct sockaddr_in {
sa_family_t sin_family; // AF_INET for TCP/IP
in port_t sinport; // port number 
struct in_addr sin_addr; // IP address
};
struct in_addr{ //internet address 
uint32_t s_addr; // IP address in network byte order 
};



二、苏格拉底大挑战

在这里插入图片描述
在这里插入图片描述

三、代码实践

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
    
#define MAXLINE 256
#define PORT 7777
void sys_err(char *msg)
{
    perror(msg);
    exit(-1);
}
int main(int argc , char **argv)
{
    int sockFd,n;
    char recvLine[MAXLINE];
    struct sockaddr_in servAddr;
    if (argc != 2) 
    {
        sys_err("usage: a.out <IPaddress>");
    }
    
    sockFd=socket(AF_INET,SOCK_STREAM,0);

    memset(&servAddr,0,sizeof(servAddr));
        
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(PORT);
    if (inet_pton(AF_INET,argv[1],&servAddr.sin_addr) <= 0) 
    {
        sys_err("inet_pton error");
    }
        
    connect(sockFd,(struct sockaddr *)&servAddr,sizeof(servAddr));
    
    
    while((n=read(sockFd,recvLine,MAXLINE)) >0 )
    {
        recvLine[n] = '\0';
        if(fputs(recvLine,stdout) == EOF)
        {
            sys_err("fputs error");
        }
    }
    if(n <0)
    {
            sys_err("read error");
    }
        return 0;
}



#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "aes_options.h"           //add

int main()
{
    int len;
    int client_sockfd;  
    struct sockaddr_in server_addr;
    char buffer[BUFSIZ];
    char *encrypt_string = NULL;
    memset(&server_addr, 0, sizeof(server_addr));

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(9000);

    if((client_sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("socket create failed");
        return 1;

    }
    int username;
    int password;
    printf("enter the username:");
    scanf("%d", &username);
    printf("enter the password:");
    scanf("%d", &password);
    if (username !=2020 || password != 1220)
    {
        printf("uncorrect name!\n");
        return 1;
    }
    
    

    if(connect(client_sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
    {
        perror("connect failed");
        return 1;
    }

    printf("connect to server\n");
    len = recv(client_sockfd, buffer, BUFSIZ, 0);

    buffer[len] = '\0';
    printf("%s", buffer);

    while(1)
    {
        printf("enter a data:");
        scanf("%s", buffer);
        if(!strcmp(buffer,"quit"))
            break;
        int encrypt_length = encrypt(buffer, &encrypt_string);     //add
        len = send(client_sockfd, encrypt_string, encrypt_length, 0); //add
        len = recv(client_sockfd, buffer, BUFSIZ, 0);
        buffer[len] = '\0';
        printf("recived:%s \n", buffer);
    }

    close(client_sockfd);
    printf("bye");


    return 0;
}

/*char username;
    int password;
    printf("enter the username:");
    scanf("%s", &username);
    printf("enter the password:");
    scanf("%d", &password);
    if (username != "cdj" || password != 20201220)
    {
        printf("uncorrect name!\n");
        return 1;
    }
    */

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值