网络编程概述

一、前言

在这里插入图片描述
小结:

  • 网络编程,可以建立多机通讯,依靠的是地址,
    地址:指的是下面的两个
    • IP地址
    • 端口号
  • 数据交流:协议(http,tcp/UDP…)
    • 单片机与PC机靠的是串口协议进行数据交流
  • Linux的协议,TCP/UDP
  • TCP/UDP的对比
端口号作用
  • 一台拥有IP地址的主机可以提供许多的服务(比如,web服务,FTP服务、SMTP服务)这些可以通过一个IP地址来实现
  • 那么主机是怎么样区分不同的网络服务的呢?
    • 单独靠IP地址是不够的,因为IP地址与网络服务的关系是一对多
    • 得通过“IP地址 + 端口号”来区分不同的服务
  • 端口号提供一种访问通道
  • 服务器一般都是通过端口号来识别 (例:对于每个TCP/IP实现来说,FTP服务器的TCP端口号都是21,Telent服务器的TCP端口号都是23,每个TFTP(简单文件传送协议)服务器的UDP端口号都是69)
字节序(点击详解)
  1. Little endian(LE):将低序字节存储在起始地址
  2. Big endian(DE):将高序字节存储在起始地址

例子:在内存中双字0x01020304(DWORD)的存储方式
内存地址
4000&4001&4002&4003

LE 04 03 02 01
BE 01 02 03 04
1

Socket服务器和客户端的开发步骤

API

1、int socket(int domain, int type, int protocol); //创建通信端点
2、int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);//用于绑定IP地址和端口号到socket
3、int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);//在套接字上发起一个连接
4、int listen(int sockfd, int backlog);//监听套接字上的连接
5、int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);//接受套接字上的连接

原型:socket

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

如果成功,将返回新套接字的文件描述符。
如果出现错误,则返回−1,并适当设置errno。
  • domin:
    域参数指定通信域;这将选择用于通信的协议族,通常为 AF_INET 表示互联网协议族(TCP/IP协议族

    • AF_UNIX, AF_LOCAL 局部通信
    • AF_INET IPv4 因特网域
    • AF_INET6 IPv6 因特网域
    • AF_UNIX Unix 域
    • AF_NETLINK 内核用户界面设备
    • AF_ROUTE 路由套接字
    • AF_KEY 密钥套接字
    • AF_UNSPEC 未指定
  • type参数指定socket的类型:

    • SOCK_STREAM:
      它使用TCP协议,提供顺序的、可靠的、双向的、基于连接的字节流。可能支持带外数据传输机制。
    • SOCK_DGRAM:
      它使用数据报协议UDP,支持数据报(固定最大长度的无连接、不可靠的消息)。
    • SOCK_RAW:
      允许程序使用底层协议,原始套接字允许对底层协议,如IPICMP进行直接访问,功能强大但使用较为不便,主要用于一些协议的开发。
  • protocol:
    通常赋值为0

    • 0 选择 type 类型对应的默认协议
    • IPPROTO_TCP TCP传输协议
    • IPPROTO_UDP UDP传输协议
    • IPPROTO_SCTP SCTP传输协议
    • IPPROTO_TIPC TIPC传输协议

原型: bind

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);

struct sockaddr {
sa_family_t sa_family;//协议族
char sa_data[14];//IP + 端口号
}
等同于
struct sockaddr_in {
  __kernel_sa_family_t  sin_family; //Address family (协议族)            
  __be16                sin_port;  // Port number(端口号)                  
  struct in_addr        sin_addr;  // Internet address(IP地址)             
  unsigned char         sin_zer0[8];//填充 没有实际意义,只是为了跟sockadd人结构体在内存中对齐,这样两者才能相互转换            
};

struct in_addr {
        __be32  s_addr;
};


如果成功,则返回0。
如果出现错误,则返回−1,并适当设置errno。

注:
地址转换为API

  • sockfd:
    函数socket的返回值(描述符)
  • addr:
    结构体
  • addrlen:
    结构体的大小(sizeof)

原型: connect

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);

如果连接或绑定成功,则返回0。
如果出现错误,则返回−1,并适当地设置errno。

原型: listen

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);

如果连接或绑定成功,则返回0。
如果出现错误,则返回−1,并适当地设置errno。
  • sockfd
    sockfd参数是一个文件描述符,它指向SOCK_STREAM或SOCK_SEQPACKET类型的套接字。
  • backlog
    backlog参数定义了sockfd的等待连接队列可能增长到的最大长度。如果一个连接请求在队列满时到达,客户端可能会收到一个指示ECONNREFUSED的错误,或者,如果底层协议支持重传,该请求可能会被忽略,以便稍后重新尝试连接时成功。

功能:

  • 设置能处理的最大连接数,listen()并未开始接受连线,只是设置socket的listen模式,listen函数只用于服务器端,服务器进程不知道要与谁连接,因此,他不会主动地要求与某个进程连接,只是一直监听是否有其他客户进程与之连接,然后响应连接请求,并对它做出处理,一个服务进程可以同时处理多个客户进程的连接。主要就两个功能:将一个未连接的套接字转换为一个被动套接字监听,规定内核为相应套接字排队的最大连接数。
  • 内核为任何一个给定监听套接字维护两个队列:
    • 未完连接队列,每个这样的SYN报文段对应其中一项: 已有某个客户端发出并到达服务器,而服务器正在等待完成相应的TCP三次握手过程,这些套接字处于SYN_REVD状态。
    • 已完成连接队列,每个已完成TCP三次握手过程的客户端对应的其中一项。这些套接字处于ESTABLISHED状态;

原型:accept

  • accept()系统调用用于基于连接的套接字类型(SOCK_STREAM, SOCK_SEQ-PACKET)。它提取侦听套接字(sockfd)的挂起连接队列上的第一个连接请求,创建一个新的连接套接字,并返回一个引用该套接字的新文件描述符。新创建的socket没有处于监听状态。处理步骤原始套接字sockfd不受此调用的影响
  • accept 函数由TCP服务器调用,用于从已完成连接队列头返回下一个已完成连接,如果已完成连接队列为空,那么进程被投入睡眠。
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

如果成功,这些系统调用将返回一个非负整数(新的套接字描述符),
已连接的套接字的描述符。
如果出现错误,则返回−1,并适当设置errno。
  • sockfd:
    sockfd参数是socket(2)创建的套接字,通过bind(2)绑定到本地地址,并在listen(2)之后监听连接。
  • addr:
    用来返回已连接的对端(客户端)的协议地址
  • addrlen:
    客户端地址长度

返回值

  • 该函数的返回值是一个新的套接字描述符,返回值是表示已连接的套接字描述符,而第一个参数是服务器监听套接字描述符。一个服务器通常仅仅创建一个监听套接字,它在该服务器的生命周期内一直存在。内核为每个有服务器进程接收的客户连接创建一个已连接套接字(表示TCP三次握手已完成),当服务器完成对某个给定客户的服务时,相应的已连接套接字就会被关闭。
代码

Socket服务器和客户端的开发步骤
小项目代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值