ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

《信息安全系统设计与实现》学习笔记11

2021-11-28 19:03:28  阅读:115  来源: 互联网

标签:11 int IP 信息安全 TCP server 笔记 line 接字


一、学习笔记

1.TCP/IP协议

      TCP/IP协议:TCP代表传输控制协议。 IP代表互联网协议。目前有两个版本的IP,即IPv4和IPv6,IPv4使用32位地址,IPv6使用128位地址。TCP/IP各个层级及使用的协议如下图所示:

2.IP

(1)IP协议

      ip协议用于在ip主机之间发送/接收数据包,但IP协议并非可靠的协议,在IP层上面实现可靠性。

(2)IP主机和IP地址

      主机是支持TCP/IP协议的计算机或设备。每个主机由一个32位的IP地址来标识。32位的IP地址号通常用点记法表示。IP地址分为两部分,即NetworkID字段和HostID字段。根据划分,IP地址分为A~E类,不同的类主机号和网络号所占位数不同。

(3)IP数据包格式

      IP数据包包括IP头、发送方IP地址、接收方IP地址、数据、数据包的总长度、数据包使用TCP还是UDP、生存时间(TTL)计数、错误检测的校验和等。每个IP数据包的大小最大为64KB。具体格式如下图

(4)路由器

      路由器是接收和转发数据包的特殊IP主机,如果IP主机相距很远,需要借助路由器来转发数据包。每个IP包在1P报头中都有一个8位生存时间(TTL)计数,其最大值为255。在每个路由器上,TTL会减小1。如果TTL减小到0,而包仍然没有到达目的地,则会直接丢弃它。

3.UDP

      UDP:用户数据报协议,在IP上运行,用于发送/接收数据报。UDP不能保证可靠性。我们常用的ping命令使用的协议就是UDP。

4.TCP

(1)TCP

      传输控制协议,是一种面向连接的协议,用于发送/接收数据流。TCP也可在IP上运行,它保证可靠的数据传输。

(2)端口编号

      在各主机上,多个应用程序(进程)可同时使用TCP/UDP.每个应用程序由三个组成部分唯一标识:应用程序=(主机IP,协议,端口号),协议是TCP或UDP,端口号是分配给应用程序的唯一无符号短整数。要想使用UDP或TCP,应用程序(进程)必须先选择或获取一个端口号。下图给出了常见的应用程序的默认端口号

5.网络和主机字节序

      计算机可以使用大端字节序,也可以使用小端字节序。在互联网上,数据始终按网络序排列,就是大端。一些库函数比如htons()、htonl()、ntohs()、ntohl()等可以在主机序和网络序之间转换数据。

6.TCP/IP网络中的数据流

      随着报文一层层下传,每一层都会在前面加上这一层专属的报头。在接收端恰恰相反,随着报文一层层上传,报头被每一层分别剥离以解析收到的数据。

7.套接字编程

(1)套接字API

      在网络编程中,TCP/IP的用户界面是通过一系列C语言库函数和系统调用来实现的,这些函数和系统调用统称为套接字API。为了使用套接字API,我们需要套接字地址结构,它用于标识服务器和客户机。netdb.hsys/socket.h中有 套接字地址结构的定义。套接字地址数据结构如下图:

服务器必须创建一个套接字,并将其与包含服务器IP地址和端口号的套接字地址绑定。客户机必须创建一个套接字。

(2)创建套接字

      socket系统调用,2种创建套接字的方法

  • int 套接字(int 域,int 类型,int 协议)
  • int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen)

(3)UDP套接字

      UDP套接字使用scndto()/recvfrom()来发送/接收数据报。

(4)TCP套接字

      在创建套接字并将其绑定到服务器地址之后,TCP服务器使用listen()和acccpt()来接收来自客户机的连接

  • int Iistcn(int sockfd, int backlog);
  • int accept(int sockfd, struct sockaddr *addr, sockien_t *addrlen);
  • int connect(int sockfd, const struct sockaddr *addr, socklen t addrlen);

      建立连接后,两个TCP主机都可以使用send()/write()发送数据,并使用recv()/read()接收数据。

8.主机名和IP地址

      如果在不同的主机上运行服务器和客户机,服务器端口号由操作系统内核分配,则需要知道服务器的主机名或IP地址及其端口号。如果某台计算机运行TCP/IP,它的主机名通常记录在/etc/hosts文件中。库函数gethostname(char *name, sizeof(name))在name数组中返回计算机的主机名字符串。struct hostent *gethostbyname(void *addr, socklen_t len, int typo)可以用来获取计算机的全名及其IP地址。

二、问题与解决办法

      运行了书上的UDP回显服务器-客户机程序

//udp_server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>

#define BUFLEN 256 // max length of buffer
#define PORT 1234 // fixed server port number 

char line[BUFLEN];
struct sockaddr_in me, client;
int sock,rlen,clen=sizeof(client);

int main()
{
    printf("1.createaUDP socket\n");
    sock =socket(AF_INET,SOCK_DGRAM, IPPROTO_UDP);

    printf("2. fill me with server address and port number\n");
    memset((char*)&me,0,sizeof(me));
    me.sin_family=AF_INET;
    me.sin_port=htons(PORT);
    me.sin_addr.s_addr=htonl(INADDR_ANY);// use localhost

    printf("3. bind socket to server IP and port\n");
    bind(sock,(struct sockaddr*)&me, sizeof(me));

    printf("4.wait for datagram\n");
    while(1)
    {
        memset(line,0,BUFLEN);
        printf("UDP server: waiting for datagram\n");

        rlen=recvfrom(sock,line,BUFLEN,0,(struct sockaddr *)&client,&clen);
        printf("received a datagram from [host:port]=[%s:%d]\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
        printf("rlen=%d:line=%s\n",rlen,line);
        printf("send reply\n");
        sendto(sock,line, rlen,0,(struct sockaddr *)&client,clen);
    }
}

//udp_client.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include <netinet/ip.h>

#define SERVER_HOST "127.0.0.1" // default server IP: localhost
#define SERVER_PORT 1234 // fixed server port number 
#define BUFLEN 256 //max length of buffer 

char line[BUFLEN];
struct sockaddr_in other,server;
int sock, rlen,slen=sizeof(server);

int main()
{
    printf("1.createaUDP socket\n");
    sock =socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    printf("2. fill in server address and port number\n");
    memset((char *) &server,0,sizeof(server));
    other.sin_family=AF_INET;
    other.sin_port=htons(SERVER_PORT);
    inet_aton(SERVER_HOST,&server.sin_addr);

    while(1)
    {
        printf("Entera line:");
        fgets(line,BUFLEN,stdin);
        line[strlen(line)-1]=0;
        printf("send line to server\n");
        sendto(sock,line,strlen(line),0,(struct sockaddr *)&server,slen);
        memset(line,0,BUFLEN);
        printf("try to receive a line from server\n");
        rlen=recvfrom(sock,line,BUFLEN,0,(struct sockaddr*)&server,&slen);
        printf("rlen=%d:line=%s\n",rlen,line);
    }
}

但是运行结果和书上的不太一样

      在两个终端分别运行两个程序,但总是运行到一半。服务器运行到接收数据报这一步就不动了,客户端也在中间卡住不运行了。暂时还没找到原因,也有可能是我的操作问题。

三、学习感悟

      网络编程里的部分知识,比如TCP/IP结构、UDP协议、数据报等在上学期计算机网络里都学过,但是这次是要编程实现它。我觉得还是有点难度的。尤其是上节课学了指针函数、函数指针等的判别方法,我感觉我还是有点混淆,所以在理解一些库函数的时候有点困难。不过我也在借助一些资料学习。希望可以加深对网络编程的理解。

标签:11,int,IP,信息安全,TCP,server,笔记,line,接字
来源: https://www.cnblogs.com/ffffatal/p/15614615.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有