Linux - 网络编程(一) - TCP

本文详细介绍网络编程的基础概念,包括网络组成、主机定义、C/S与B/S架构的区别、网络分层原理、IP地址及端口的作用,并深入探讨TCP与UDP协议的编程实现。

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

======================

No.1 网络编程基础

1.1 网络

多个主机连到一起,就形成了网络。
在这里插入图片描述

1.2 主机

并非必须得是一台计算机,共享单车、共享充电宝、路由器、空调、智能开关等都是主机,只要具备网络功能的计算机都是主机。具有网络模块的芯片也算是一个主机。

1.3 C/S B/S

  • 服务器:提供指定服务的机器(功能单一)
  • 客户端:界面 用来和用户交互
  • C/S: Clinet/Server 客户端/服务器 (单一)
  • B/S: Browser/Server 浏览器/服务器 (繁杂)

1.4 网络分层

  • 应用:
    ftp http https smtp ppppoe这种协议
  • 传输:
    数据的具体传输方式 Tcp(中心化)/Udp(去中心化)
  • 网络:
    ip 往哪里发
  • 数据链路:加密 翻译 编解码
    字节
  • 物理:硬件(网卡)
    硬件层次传电信号或者光信号(光纤,光缆,双绞线)

1.4 协议

约定的规则

  • 公有协议:全世界通用的标准 tcp udp http 公历纪元
  • 私有协议:某些公司或者个人制定的标准

1.5 ip

  • IP地址 协议 ipv4 ipv6
    区分网络中的主机,本质就是一个整数

1.6 端口

  • 一台主机为了区分不同应用(不同进程)所以有多个网络端口,同一时刻,有且只能一个进程使用某个端口进行通信。

No.2 TCP

	tcp协议编程模型
	Server							Client
	1. 创建socket					1. 创建socket
		socket 返回一个描述符号(类似文件描述符号)
	2. 确定服务器协议地址簇			2. 获取服务器协议地址簇
		struct sockaddr
	3. 绑定
		bind
	4. 监听
		listen
	5. 接收客户端连接					3. 连接服务器
		accept							connect
	6. 通信							4. 通信
		recv	send
	7. 断开连接						5. 断开连接
		close
  • 建立稳定全双工稳定数据传输通道:
    • 打电话 直播 一直不间断的
    • 发短信 断断续续的
    • 全双工:双向同时进行
#include <sys/types.h>
#include <sys/socket.h>
/*返回一个网络描述符好,类似文件描述符号,一半被翻译为套接字,
时网络设备的映射,操作套接字就是在操作对应的网络设备*/
int socket(
	int domain,		//协议类型	AF_LOCAL AF_INET
	int type,		//媒介类型 	SOCK_STREAM
	int protocol);	//保护类型	0默认

Client

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<signal.h>
int clinentSocket;
int serverFd;
void handler(int num)
{
    if(num==2)
    {
        close(serverFd);
        close(clinentSocket);
        printf("关闭客户端!\n");
        exit(0);
    }
}

int main(int argc,char* argv[])
{
    signal(2,handler);
    if(argc!=3) printf("cmd err!\n"),exit(0);
    //创建
    serverFd = socket(AF_INET,SOCK_STREAM,0);
    if(-1==serverFd) printf("创建socket失败:%m\n"),exit(-1);
    printf("创建socket成功!%m\n");

    //协议地址簇
    struct sockaddr_in addr = {0};
    addr.sin_family = AF_INET;  //与socket的第一个参数一致
    addr.sin_addr.s_addr = inet_addr(argv[1]);//字符串转为整形 需要注意大小端的问题
    addr.sin_port = htons(atoi(argv[2]));//端口号
    
    //连接服务器
    int r = connect(serverFd,(struct sockaddr*)&addr,sizeof addr);
    if(-1==clinentSocket) printf("连接服务器失败:%m\n"),close(serverFd),exit(-1);
    printf("连接服务器成功!%m\n");


    //通信
    char buff[256];
    while(1)
    {
        memset(buff,0,256);
        r = 0;
        printf("请输入>>");
        scanf("%s",buff);
        r = send(serverFd,buff,strlen(buff),0);
        if(r<0)
        {
            printf("发送失败!\n");
        }
    }
    return 0;
}

Server

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<signal.h>
int clinentSocket;
int serverFd;
void handler(int num)
{
    if(num==2)
    {
        close(serverFd);
        close(clinentSocket);
        printf("关闭服务器!\n");
        exit(0);
    }
}

int main(int argc,char* argv[])
{
    signal(2,handler);
    if(argc!=3) printf("cmd err!\n"),exit(0);
    //创建
    serverFd = socket(AF_INET,SOCK_STREAM,0);
    if(-1==serverFd) printf("创建socket失败:%m\n"),exit(-1);
    printf("创建socket成功!%m\n");

    //协议地址簇
    struct sockaddr_in addr = {0};
    addr.sin_family = AF_INET;  //与socket的第一个参数一致
    addr.sin_addr.s_addr = inet_addr(argv[1]);//字符串转为整形 需要注意大小端的问题
    addr.sin_port = htons(atoi(argv[2]));//端口号
    
    //绑定(很容易失败)
    int r = bind(serverFd,(struct sockaddr*)&addr,sizeof addr);
    if(-1==r) printf("绑定失败:%m\n"),close(serverFd),exit(-1);
    printf("绑定成功!%m\n");

    //监听
    r = listen(serverFd,10);
    if(-1==r) printf("监听失败:%m\n"),close(serverFd),exit(-1);
    printf("监听成功!%m\n");

    //接受客户端连接
    clinentSocket = accept(serverFd,NULL,NULL);
    if(-1==clinentSocket) printf("接受客户端连接失败:%m\n"),close(serverFd),exit(-1);
    printf("接受客户端连接成功!%m\n");

    //通信
    char buff[256];
    while(1)
    {
        r = recv(clinentSocket,buff,255,0);
        if(r>0)
        {
            buff[r] = 0;
            printf("<< %s\n",buff);
        }
    }
    return 0;
}

No.3 UDP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值