网络编程 tcp udp http编程流程 网络基础知识

这篇具有很好参考价值的文章主要介绍了网络编程 tcp udp http编程流程 网络基础知识。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

网络基础知识

OSI分层:应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
tcp/ip: 应用层 传输层 网络层 数据链路
ip地址:唯一标识一台主机
ipv4 32位 ipv6 128位 寻址 可以反映物理上的一个变化
MAC地址:48 固化在计算机中
ip地址又两部分构成:网络号+主机号
端口号:标识一个应用程序的代号 短整型
协议:共同遵守的约定 tcp协议 网络中的规则
ip , http/https,/ftp, tcp/
ipv4头部结构
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
4位头部长度:表示15行 每行4字节就是60字节 减去 基本的20字节 剩余的选项 40字节
TCP头部结构
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp

剩余的选项仍然是 40字节
应用程序传递数据的一个过程
tcp协议

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
这四层:应用层 传输层 网络层 数据链路

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
ip地址由网络号和主机号共同构成的

"129.168.1.1"点分十进制转化为
无符号整型:
unsignal int inet_addr();
无符号整型转化为点分十进制:
inet_ntoa();
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
每一个字节8位 都是十进制转化的,最后将四个字节组合在一起,变成一个无符号整型

大端:网络字节序列 htons()
地址:ip+port

表示Ipv4的地址结构

struct socketaddr_in ipv4;

通用的套接字地址

struct socketaddr;

套接字
像手机一样进行数据的收发

需要让服务器先运行起来,客户端主动连接服务器,所以服务器需要把自己的ip 和端口告诉客户端

在Windows下查看ip地址

ipconfig

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp

Linux下查看虚拟机ip地址

ifconfig

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
判断两个主机是否连通

ping 

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
无法访问目标主机 ,说明该网络下没有这个主机
请求超时,可能有防火墙 没有成功

网络编程

tcp编程流程

图示理解

tcp服务器 ,客户端编程流程
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp

bind和accept函数理解

bind就是看看saddr得ip地址端口有没有问题,ip地址是不是写错了,端口是不是被占用了,如果没有问题,就将表示符合该地址绑定,取名成功

int c = accept(sockfd, (struct sockaddr *)&caddr, &len);

服务器会在该行阻塞,等待用户端的连接,一旦connect成功,阻塞结束,得到新的描述符c,该c对应刚才的客户端,类似一个链接,每个c都对应一个客户端,表示一条链接。

监视套接字和链接套接字理解

监听套接字 都是这一个 类似文件描述符 在一个进程中,fd都是3 不变
链接套接字:一个链接 由于服务器012 被占用 监视套接字是3 所以链接套接字从4开始,说明一个客户端和服务器链接上了,如果另一个客户端链接,那就是5 …
如果不理解,可以看这篇文章,讲的挺通俗易懂的:
监视套接字和链接套接字

int c = accept(sockfd,(struct sockaddr*) &caddr,&len);//阻塞
服务器刚开始是不知道客户端的地址的,所以先 &caddr 把结构体放这里,等客户端根据服务器给的ip端口找到connect,此时accept接收,这个时候就知道了客户端的地址和ip,存储在caddr

为什么c变成了4 原来的sockfd是3 而客户端的sockfd一直是3
类似用你的手机3给10086电话,你的电话号不变,一直是3 服务器类似一个服务中心,服务器刚开始也是10086 即3号手机接收,接听到了一个用户,就转接到另一个人工客服接听,即4 号手机,原来的3号手机继续接听客户的电话。一次类推。

linux和window下的编程实现

ser.c

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

int main()
{
    int sockfd = socket (AF_INET,SOCK_STREAM,0);
    if(sockfd == -1)
    {
        exit(1);
    }

    struct sockaddr_in saddr, caddr;
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(6000);
    saddr.sin_addr.s_addr = inet_addr("192.168.1.49");//“127.0.0.1”

    int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if ( res == -1)
    {
        printf("bind err\n");
        exit(1);
    }

    res = listen(sockfd,5);
    if ( res == -1 )
    {
        exit(1);
    }

    while( 1 )
    {
        socklen_t len = sizeof(caddr);
        int c = accept(sockfd,(struct sockaddr*) &caddr,&len);//阻塞
        if ( c < 0 )
        {
            continue;
        }

        printf("accept c=%d\n",c);

        char buff[128] = {0};
        int n = recv(c,buff,127,0);//阻塞
        printf("buff=%s\n",buff);
        send(c,"ok",2,0);
        close(c);
    }
}

cli.c

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

int main()
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if ( sockfd == -1)
    {
        exit(1);
    }

    struct sockaddr_in saddr;
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(6000);
    saddr.sin_addr.s_addr = inet_addr("192.168.1.49");

    int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if ( res == -1)
    {
        printf("connect err\n");
        exit(1);
    }

    send(sockfd,"hello",5,0);
    char buff[128] = {0};
    recv(sockfd,buff,127,0);//ok
    printf("buff=%s\n",buff);

    close(sockfd);
}

Windows系统上的服务器和客户端

//window servier
#if 0
//ConsoleApptcp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <WinSock2.h>   //网络头文件
#include <string.h>
#include <ws2tcpip.h>  //socklen_t
#include <iostream>


using namespace std;
#pragma comment(lib, "ws2_32.lib")   //网络库文件


//初始化网络库
void InitNetwork() {
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(2, 2);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		return;
	}

}


int main()
{
	InitNetwork();
	SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == INVALID_SOCKET)
	{
		cout << "socket err" << endl;
		return 0;
	}

	struct sockaddr_in saddr;
	memset(&saddr, 0, sizeof(saddr));
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(6000);
	//saddr.sin_addr.S_un.S_addr = INADDR_ANY;
	saddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.32");//这个要用需要加宏定义
	//saddr.sin_addr.S_un.S_addr = inet_pton(AF_INET,"192.168.1.50",NULL);

	int res = bind(sockfd, (SOCKADDR*)&saddr, sizeof(saddr));
	if (res == SOCKET_ERROR)
	{
		cout << "bind err" << endl;
		return 0;
	}

	if (listen(sockfd, 5) == SOCKET_ERROR)
	{
		cout << "listen err" << endl;
		return 0;
	}

	while (true)
	{
		//struct sockaddr_in caddr;
		SOCKADDR_IN caddr;
		socklen_t len = sizeof(caddr);

		int c = accept(sockfd, (SOCKADDR*)&caddr, &len);
		if (c == INVALID_SOCKET)
		{
			continue;
		}
		cout << "accept c=" << c << endl;

		char buff[128] = { 0 };

		while (true)
		{
			if (recv(c, buff, 127, 0) <= 0)
			{
				break;
			}

			cout << buff << endl;
			send(c, "ok", 2, 0);
		}

		closesocket(c);

	}

}
#endif



//windows client 
#if 0
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <WinSock2.h>   //网络头文件
#include <string.h>
#include <ws2tcpip.h>  //socklen_t
#include <iostream>


using namespace std;
#pragma comment(lib, "ws2_32.lib")   //网络库文件


//初始化网络库
void InitNetwork() {
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(2, 2);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		return;
	}

}

int main()
{
	InitNetwork();
	SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == INVALID_SOCKET)
	{
		cout << "socket err" << endl;
		return 0;
	}

	struct sockaddr_in saddr;
	memset(&saddr, 0, sizeof(saddr));
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(6000);
	saddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.49");

	int res = connect(sockfd, (struct sockaddr*)&saddr, sizeof(saddr));
	if (res == -1)
	{
		cout << "connect err" << endl;
		closesocket(sockfd);
		WSACleanup();
	}

	while (true)
	{
		cout << "input" << endl;
		char buff[128] = { 0 };
		cin >> buff;

		if (strncmp(buff, "end", 3) == 0)
		{
			break;
		}

		send(sockfd, buff, strlen(buff), 0);
		memset(buff, 0, 128);
		recv(sockfd, buff, 127, 0);
		cout << buff << endl;
	}

	closesocket(sockfd);
	WSACleanup();

	return 0;
}
#endif

tcp特点

 int n = recv(c,buff,1,0);

一次只收一个字符
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp

当发送速度快,会一起写到缓冲区,然后一起发送,数据太大,会拆开发送
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
套接字有发送缓冲区和接收缓冲区

netstat

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
应答确认 超时重传
乱序重拍 去重
滑动窗口控制
tcp特点
面向连接的 可靠的 流式服务

udp编程流程

图示理解

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp

udp特点

无连接 不可靠 数据报服务
双方无连接:服务器关了,再起启动,发送消息还是能收到,在建立一个客户端,也可以发送信息。
udp发送数据时,要保证数据收完,否则其他数据就丢了
严格的一对一,发几次收几次

一个端口可以被一个套接字绑定,可以绑定两个,是协议不同
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
tcp在应用层面不丢数据,底层会丢,网络层,丢了重发就行,tcp自身保证其可靠性
tcp适合传文件 丢一个字节都不行
udp适合视频通话 丢包就是卡了

http编程流程

图示+理解

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp

应用层 http 浏览器和服务器之间的通讯
传输层 tcp

两次以上的请求复用了同一个tcp连接,就是长连接
http用80号端口
https用443号端口
小于1024的端口,需要管理员才能访问
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
后面有\r\n结束

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
最后一行还有一个\r\n
content_length 不包含报头
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
服务器收到浏览器的信息,放到buff数组里,服务器知道了浏览器想访问的资源就是index.html,服务器需要做的是找到该资源,发给浏览器就行

网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp
浏览器会自己发起一个请求,去访问图标
这是一组请求,可能会有多次请求,在一次点击的过程中
网络编程 tcp udp http编程流程 网络基础知识,计算机网络基础,网络,tcp/ip,udp

编程实现-网站服务器

myhttp.c文章来源地址https://www.toymoban.com/news/detail-642793.html

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include<fcntl.h>
#define PATH "/home/ittao/code/day17"
int socket_init();
char *get_filename(char buff[])
{
    if(buff==NULL){
        return NULL;
    }
    char *ptr=NULL;
    char*s=strtok_r(buff," ",&ptr);
    if(s==NULL){
        return NULL;
    }
    printf("way:%s\n",s);
    s=strtok_r(NULL," ",&ptr);
    return s;
}
void *thread_fun(void *arg)
{
    int c = (int)arg;
    while (1)
    {
        char buff[4096] = {0};
        int n = recv(c, buff, 4095, 0);
        if(n<=0){
            break;
        }
        printf("buff:%s\n", buff);
        char*filename=get_filename(buff);
        if(filename==NULL){
            send(c,"http err:404",12,0);
            break;
        }
        printf("filename:%s\n",filename);
        char path[256]={PATH};
        if(strcmp("/",filename)==0){
            strcat(path,"/index.html");
        }else{
            strcat(path,filename);
        }
        int fd=open(path,O_RDONLY);
        if(fd==-1){
            send(c, "http err:404", 12, 0);
        }
        int filesize=lseek(fd,0,SEEK_END);
        lseek(fd,0,SEEK_SET);

        char http_head[256]={" my HTTP/1.1 200 OK\r\n"};
        strcat(http_head,"Server:myhttp\r\n");
        sprintf(http_head+strlen(http_head),"Content-Length:%d\r\n",filesize);
        strcat(http_head,"\r\n");
        send(c,http_head,strlen(http_head),0);

        char data[1024];
        int num=0;
        while((num=read(fd,data,1024))>0){
            send(c,data,num,0);
        }
        close(fd);
    }
    close(c);
    printf("client close\n");
    pthread_exit(NULL);
}
int accept_client(int sockfd)
{
    struct sockaddr_in caddr;
    int len = sizeof(caddr);
    int c = accept(sockfd, (struct sockaddr *)&caddr, &len);
    return c;
}
int main()
{
    int sockfd = socket_init();
    if (sockfd == -1)
    {
        exit(1);
    }
    while (1)
    {
        int c=accept_client(sockfd);
        if (c != -1)
        {
            pthread_t id;
            pthread_create(&id, NULL, thread_fun, (void *)c);
        } 
    }
}
int socket_init()
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1)
    {
        return -1;
    }
    struct sockaddr_in saddr;
    memset(&saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(80);
    saddr.sin_addr.s_addr = inet_addr("192.168.1.49");
    int res = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
    if (res == -1)
    {
        printf("bind err\n");
        return -1;
    }

    res = listen(sockfd, 5);
    if (res == -1)
    {
        return -1;
    }
    return sockfd;
}

到了这里,关于网络编程 tcp udp http编程流程 网络基础知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】6.网络编程:网络编程(TCP&UDP)

    网络编程是C++ API操作中很重要的一部分,包含 TCP 和 UDP 。 网络传输模型可以抽象为7个层: 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层 。 但在使用TCP/IP协议时,可以简化为这4层: 网络接口、网络层、传输层、应用层 。 TCP:可靠传输,三次握手建立

    2024年02月16日
    浏览(33)
  • 网络编程 —— TCP 和 UDP 编程详解

    目录 网络编程主要函数介绍 1. socket 函数 2. bind 函数 3. listen 函数 4. accept 函数 5. connect 函数 6. send 函数 7. recv 函数 8. recvfrom 函数 9. sendto 函数 TCP 和 UDP 原理上的区别 TCP 编程 服务端代码: 客户端代码: UDP 编程 服务端代码: 客户端代码: 1. socket 函数 int socket(int domain, int

    2024年02月04日
    浏览(35)
  • 网络编程、UDP、TCP

    就是将地理位置不同的具有独立功能的多台计算及外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件以及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统 传播交流信息、数据交换、通信 1.如何准确定位网络上的一台主机 192.xxx.xx.xx:端

    2024年03月10日
    浏览(39)
  • 基于TCP、UDP网络编程

    应用层 : 应用程序拿到数据怎么用 传输层 : 负责关注传输过程中起点和终点 网络层 :负责整个传输过程中的路线规划 数据链路层 :负责相邻节点之间的数据传输 物理层 : 基础设施,硬件设备 程序员写网络程序,主要编写的应用层代码,真正要发这个数据,调用下层协

    2024年02月07日
    浏览(40)
  • UDP和TCP网络编程

    特点: 无连接:发送数据前不需要建立连接。 不可靠:没有重发机制,无法保证数据的可靠性和顺序。 无拥塞控制:发送方发送数据的速度受限于网络的带宽。 快速:由于没有连接建立和拥塞控制的处理,UDP的传输速度通常比TCP快。 简单:UDP协议的头部较小,仅有8个字节

    2024年02月11日
    浏览(38)
  • TCP和UDP网络编程

    TCP和UDP协议是TCP/IP协议的核心。 TCP 传输协议:TCP 协议是一TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠

    2023年04月08日
    浏览(36)
  • 【网络编程】TCP,UDP协议详解

    小亭子正在努力的学习编程,接下来将开启javaEE的学习~~ 分享的文章都是学习的笔记和感悟,如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话,烦请点赞关注支持一波, 感激不尽~~   目录 前言 TCP协议 TCP协议特点 TCP协议通信场景 TCP协议的几个重要机制 一、

    2023年04月19日
    浏览(45)
  • 网络编程(TCP与UDP协议)

    Java是 Internet 上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序。 Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在 Java 的本机安装系统里,由 JVM 进行控制。并且 Java 实现了一个跨平台的网络库, 程序

    2023年04月27日
    浏览(43)
  • Java网络编程(UDP、TCP)

    在网络通信协议下,不同计算机上运行的程序,进行的数据传输。 应用场景:即时通信、网游对战、金融证券、国际贸易、邮件、等等。 不管是什么场景,都是计算机跟计算机之间通过网络进行数据传输。 Java中可以使用java.net包下的技术轻松开发出常见的网络应用程序。

    2024年02月05日
    浏览(53)
  • 【Java学习笔记】 68 - 网络——TCP编程、UDP编程

    https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter21/src 目录 项目代码 网络 一、网络相关概念 1.网络通讯 2.网络 3.IP地址 4.域名 5.端口号 6.网络通讯协议 TCP协议:传输控制协议 UDP协议: 二、InetAddress类 1.相关方法 三、Socket 1.基本介绍 2.TCP网络通信编程 基本介绍 应用案例

    2024年02月04日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包