首页 > 其他分享 >学习笔记11

学习笔记11

时间:2023-11-24 20:57:18浏览次数:35  
标签:11 addr IP 笔记 server 学习 printf line include

20211301 学习笔记11

教材知识点总结

TCP/IP协议

  • TCP:代表传输控制协议

  • IP:代表互联网协议

  • IPv4:32位

  • IPv6:64位

  • 堆栈

  • 顶层:应用程序,用于登录远程主机ssh、用于交换电子邮件、用于web页面的http等应用程序需要可靠的数据传输

  • 网络中的数据流路径:

IP主机和IP地址

  • 主机是支持TCP/IP协议的计算机或设备,每个主机由一个32位的IP地址来标识

  • 主机也可以用主机名来表示,如dnsl.eec.wsuedu

  • 主机名就等同于IP 地址,因为给定其中一个,我们可以通过DNS(域名系统)(RFC1341987:RFC 10351987)服务器找到另一个

  • IP地址分为两部分,即NetworkID 字段和HostID字段

  • 发往IP地址的数据包首先被发送到具有相同networkID的路由器

  • 每个主机都有一个本地主机名localhost,默认IP地址为127.0.0.1本地主机的链路层是一个回送虚拟设备,它将每个数据包路由回同一个localhost。这个特性可以让我们在同一台计算机上运行TCP/IP应用程序而不需要实际连接到互联网

IP协议

  • IP 协议用于在IP 主机之间发送/接收数据包。IP 尽最大努力运行。IP 主机只向接收主机发送数据包,但它不能保证数据包会被发送到它们的目的地,也不能保证按顺序发送。这意味着 IP 并非可靠的协议。

IP数据包格式

  • IP 数据包由IP头、发送方IP 地址和接收方P 地址以及数据组成。每个IP 数据的大小最大为64KB。IP 头包含有关数据包的更多信息,例如数据包的总长度、数据包使用TCP还是UDP、生存时间(TTL)计数、错误检测的校验和

路由器

  • IP 主机之间可能相距很远。通常不可能从一个主机直接向另一个主机发送数据包。

  • 了TCP/IP 网络的拓扑结构:

  • 每个IP包在IP报头中都有一个8位生存时间(TTL)计数,其最大值为255。在每个路由器上,TTL会减小1。如果 TTL减小到0,而包仍然没有到达目的地,则会直接丢弃它。这可以防止任何数据包在IP网络中无限循环

UDP

  • UDP(用户数据报协议)(RFC 768 1980: Comer1988)在IP上运行用于发送/接收数据报。与IP类似,UDP不能保证可靠性,但是快速高效。它可用于可靠性不重要的情况

  • ping主机名或pingP地址:ping是一个向目标主机发送带时间戳UDP包的应用程序。接收到一个pinging数据包后,目标主机将带有时间戳的UDP 包回送给发送者,让发送者可以计算和显示往返时间

TCP

  • TCP(传输控制协议)是一种面向连接的协议,用于发送/接收数据流。TCP也可在IP上运行,但它保证了可靠的数据传输。通常,UDP类似于发送邮件的USPS,而TCP类似于电话连接。

端口编号

  • 应用程序=(主机IP,协议,端口号)

网络和主机字节序

  • 计算机可以使用大端字节序,也可以使用小端字节序。在互联网上,数据始终按网络序排列,这是大端。在小端机器上,例如基于Intelx86的PC,htons、htonl0、ntohs0ntoh10等库函数,可在主机序和网络序之间转换数据。

  • 必须先通过 htons(1234)把它转换成网络序,才能使用。相反,从互联网收到的端口号必须先通过ntohs(port)转换为主机序。

TCP/IP网络中的数据流

网络编程

  • 所有linux都支持

  • 通过下面几种方法访问

    • 服务器上的用户账户
    • 单独PC或笔记本电脑
  • 服务器-客户机计算模型

    • 首先在服务器主机上运行服务器进程,然后从客户机主机运行客户机

套接字编程

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

  • 服务器必须创建一个套接字,并将其与包含服务器IP 地址和端口号的套接字地址绑定。它可以使用一个固定端口号,或者让操作系统内核选择一个端口号(如果sin port为0)。为了与服务器通信,客户机必须创建一个套接字。对于UPD套接字,可以将套接字绑定到服务器地址。如果套接字没有绑定到任何特定的服务器,那么它必须在后续的 sendto()recvfrom0调用中提供一个含服务器IP和端口号的套接字地址。下面给出了scket0系统调用,它创建一个套接字并返回一个文件描述符

UDP回显服务器-客户机程序

  • 。服务器在默认本地主机上运行(IP = 127.0.0.1)使用固定端号1234。这可以简化程序代码。读者可以在同一台计算机上以不同的xterms测试运行服务器和客户机程序。

TCP回显服务器-客户机程序

  • 设服务器和客户机都在同一台计算机上运行,服务器端口号硬编码为1234

主机名和IP地址

  • 假设服务器和客户机在同一台计算机上运行,并且服务器使用固定端口号

代码实现

  • 13.14 server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFLEN 256
#define PORT 1234

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

int main() {
    printf("1. create a UDP 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);
    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);
    }

    return 0;
}
  • client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>  // Added inclusion of arpa/inet.h for inet_aton function
#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 server;
int sock, rlen, slen = sizeof(server);

int main() {
    printf("1. create a UDP 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));
    server.sin_family = AF_INET;
    server.sin_port = htons(SERVER_PORT);
    inet_aton(SERVER_HOST, &server.sin_addr);  while (1) {
        printf("Enter a line: ");
        fgets(line, BUFLEN, stdin);
        line[strlen(line) - 1] = '\0';  // Fixed newline character removal
        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);
    }

    return 0;
}

  • 13.15 server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>

#define MAX 256
#define SERVER_PORT 1234

int mysock, csock;
struct sockaddr_in server_addr, client_addr;

int server_init()
{
    printf("================== server init =====================\n");
    
    printf("1 : create a TCP STREAM socket\n");
    mysock = socket(AF_INET, SOCK_STREAM, 0);
    if (mysock < 0) {
        printf("socket call failed\n");
        exit(1);
    }

    printf("2 : fill server_addr with host IP and PORT# info\n");
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(SERVER_PORT);

    printf("3 : bind socket to server address\n");
    int r = bind(mysock, (struct sockaddr*)&server_addr, sizeof(server_addr));
    if (r < 0) {
        printf("bind failed\n");
        exit(3);
    }

    printf("port = %d\n", SERVER_PORT);
    printf("4 : server is listening ....\n");
    listen(mysock, 5);

    printf("================ init done ===========================\n");
}

int main()
{
    char line[MAX];

    server_init();

    while (1) {
        printf("server: accepting new connection ....\n");
        socklen_t len = sizeof(client_addr);
        csock = accept(mysock, (struct sockaddr *)&client_addr, &len);
        if (csock < 0) {
            printf("server: accept error\n");
            exit(1);
        }

        printf("server: accepted a client connection from\n");
        printf("----------------------------\n");
        printf("Client: IP=%s port=%d\n", inet_ntoa(*(struct in_addr*)&client_addr.sin_addr.s_addr), ntohs(client_addr.sin_port));
        printf("----------------------------\n");

        while (1) {
            int n = read(csock, line, MAX);
            if (n <= 0) {
                printf("server: client died, server loops\n");
                close(csock);
                break;
            }

            line[n] = '\0'; // Ensure null-terminated string

            printf("server: read n=%d bytes; line=%s\n", n, line);

            n = write(csock, line, n);
            printf("server: wrote n=%d bytes; ECHO=%s\n", n, line);
            printf("server: ready for next request\n");
        }
    }
}

  • client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>

#define MAX 256
#define SERVER_HOS "localhost"
#define SERVER_PORT 1234
struct sockaddr_in server_addr;
int sock,r;
int client_init()
{
printf("======= clinet init ==========\n");
printf("1 : create a TCP socket\n");
sock = socket(AF_INET, SOCK_STREAM,0);
if (sock<0){
printf("socket call failed\n"); exit(1);
}
printf("2 : fill server_addr with server's IP and PORT#\n");
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);// localhost
server_addr.sin_port = htons(SERVER_PORT); // server port number
printf("3 : connecting to server ....\n");
r = connect(sock,(struct sockaddr*)&server_addr, sizeof(server_addr));
if(r<0){
printf("connect failed\n");exit(3);
}
printf("4 : connected OK to\n");
printf("--------------------------------------------\n");
printf("Server hostname=%s PORT=d\n",SERVER_HOS,SERVER_PORT);
printf("-----------------------------------------\n");
printf("=========init done ==========\n");
}
int main()
{
	int n;
	char line[MAX],ans[MAX];
	client_init();
	printf("************processing loop **********\n");
	while (1){
printf("input a line :");
bzero(line,MAX);
fgets(line,MAX,stdin);
line[strlen(line)-1] = 0;
if (line[0]==0)
exit(0);// Send line to server
n = write(sock,line, MAX);
printf("client: wrote n=%d bytes; line=%s\n",n,line);// Read a line from sock and show it
n = read(sock, ans, MAX);
printf("client: read n=%d bytes; echo=%s\n",n,ans);
}
}

苏格拉底挑战

  • 大端小端


  • 套接字编程





标签:11,addr,IP,笔记,server,学习,printf,line,include
From: https://www.cnblogs.com/pengqiqi/p/17854493.html

相关文章

  • 排列组合学习笔记
    加法原理有\(n\)类办法,\(a_i(1\lei\len)\)代表第\(i\)类方法的数目。那么共有\(S=a_1+a_2+\cdots+a_n\)种方法乘法原理分\(n\)个步骤,\(a_i(1\lei\len)\)代表第\(i\)个步骤的方法数目。那么共有\(S=a_1\timesa_2\times\cdots\timesa_n\)种方法排列数从\(n\)个......
  • [Luogu] P7911 [CSP-J 2021] 网络连接
    [CSP-J2021]网络连接-洛谷距离CSP2023还有\(**3**\)天题意及思路恶臭大模拟,按照题意模拟即可。有几个代码上的难点:当定义了一个scanf或者sscanf并且有一定的输入规则,那么如果读取到的字符串不符合定义的规则,那读入了几个变量就返回几个变量例如,如下代码定义了一个读......
  • [Luogu] P1164 小A点菜
    题目传送门一道动态规划,\(dp_{i, j}\)表示用前\(i\)个菜品花光\(j\)元的方法总数那么可以推出状态转移方程:\(if(j>a_i)\spacedp_{i,j}=dp_{i-1,j}+dp_{i-1,j-a_{i}}\)如果j比ai大,那么方案数就是不买\(dp_{i − 1, j}\)+买\(dp_{i − 1, j − a_i}\),其中如果买,那么......
  • [Luogu] P1114 “非常男女”计划
    https://www.luogu.com.cn/problem/P1114暴力,前缀和,稍加优化可以拿100,但是#1加强过后就AC不了了#include<bits/stdc++.h>usingnamespacestd;constintmaxn=2e6;inta[maxn],n,f[maxn],ans,boy;intmain(){ cin>>n; for(inti=1;i<=n;i++) { scanf("%d",a......
  • stm32学习随笔23.11.24
    探索TIM2两个PWM输出视频:B站BV1vb4y1T72LMain.C主函数部分节选#include"stm32f10x.h"                 //Deviceheader#include"Delay.h"#include"OLED.h"#include"TestLED.h"#include"PWM.h"#include"KEY.h"#incl......
  • 【刷题记录】20231124 线段树分治
    做题记录:注意到每次相当于\(0\)后面加\(1\),\(1\)后面加\(0\),因此每次可以合并01和10然后将问题规模减半。黑白染色,白格子=lcm+1,黑格子=prime相乘。发现横着竖着有六个质数,斜着只用四个质数。调整一下顺序即可。状压DP。考虑S作为前缀max时S与U-S的排列方案数。S每......
  • 2023-2024-1 20231320 《计算机基础与程序设计》第九周学习总结
    2023-2024-120231320《计算机基础与程序设计》第九周学习总结作业信息这个作业属于哪个课程<班级的链接>(2023-2024-1计算机基础与程序设计)这个作业要求在哪里<作业要求的链接>(2022-2023-1计算机基础与程序设计第九周作业)这个作业的目标<自学《计算机基础与......
  • 11.24每日总结
    今天完成了大数据的测试,这一次没有用hadoop用的是python直接对数据的导入、清洗、分析和可视化展示的操作,下面是所有的代码。 importtorchimporttorch.nnasnnimporttorch.optimasoptimfromtorch.utils.dataimportDataLoader,TensorDatasetfromsklearn.mod......
  • 2023-2024-1 20211306 密码系统设计与实现课程学习笔记11
    20211306密码系统设计与实现课程学习笔记11任务详情自学教材第13章,提交学习笔记知识点归纳以及自己最有收获的内容,选择至少2个知识点利用chatgpt等工具进行苏格拉底挑战,并提交过程截图,提示过程参考下面内容“我在学***X知识点,请你以苏格拉底的方式对我进行提问,一次一个......
  • 一、Hadoop概述与初步学习
    一、Hadoop的发展史 Google 爬取全球的网站,然后计算页面的PageRank 要解决网站的问题: a:这些网站怎么存放 b:这些网站应该怎么计算 发布了三篇论文 a:GFS(GoogleFileSystem) b:MapReduce(数据计算方法) c:BigTable-->HBase Dougcutting花费......