Linux:网络编程  (上)

时间:2022-03-13 15:33:31

网络基本知识概要:

  1. TCP/IP参考模型:应用层,传输层,网络层,网络接口层.
  2. 网络层协议:Internet协议(IP),网络控制报文协议(ICMP),地址解析协议(ARP).
  3. 传输层协议:传输控制协议(TCP),用户数据报文协议(UDP).
  4. 协议封装:以太网---->>IP---->>TCP(UDP)---->>应用层.
  5. 以太网包:|目的地址(2/6)|源地址(2/6)|数据字段长度(2)|数据(0~1500)|填充字段(0~46)|校验(4)|

 

IP协议:数据传送,寻址,路由选择,数据报文分段.

分为:1.IP协议头,  2.IP数据(在以太网包的数据段).

 

TCP协议:位于IP包的数据部分.

分为:1.TCP协议头, 2.TCP数据.

 

Linux:网络编程通过Socket(套接字)实现 , Socket是一种文件描述.

Socket有三种类型:

  1. 流式套接字(SOCK_STREAM), 用于TCP协议.
  2. 数据报套接字(SOCK_DGRAM), 用于UDP协议.
  3. 原始套接字(SOCK_RAW),  允许使用IP协议,主要用于新的网络协议测试.

 

网络编程中常用的 函数以及结构体:

  1. 网络地址:structsockaddr 和 struct sockaddr_in 用于记录网络地址.

struct sockaddr {

u_short sa_family; \\协议族,用于记录协议族的种类.

charsa_data[14];   \\ 14字节特定协议地址.

};

(常用的是structsockaddr_in 记录地址)

struct sockaddr_in {

short int sin_family; \\协议族.

unsigned short int sin_port;\\端口.

struct in_addr sin_addr;\\协议特定地址.

unsigned char sin_zero[8]; \\填0;

};

 

typedef struct in_addr {

union {

             struct {

                             unsigned char s_b1, s_b2,  s_b3, s_b4;

                         }S_un_b;

             struct {

                              unsignedshort s_w1, s_w2;

                        }S_un_w;

              unsignedlong s_addr;  \\常用这个;

           }S_un;

 }IN_ADDR;

 

IP地址32位<<==>>字符串(a.b.c.d)转化:

int inet_aton(const char *cp, struct in_addr*inp)

a代表:acsII    n代表:network.

功能:将a.b.c.d形式转化为32位的IP存储在inp指针中.

 

char *inet_ntoa(struct in_addr in)

功能:将32位的IP转化为a.b.c.d形式,返回字符串的首地址.

 

 2.网络字节序:bigendian(大端口)

转换字节序:

(1). u_short htons(u_shorthostshort)

功能:将主机序转化为网络序.

返回:16为无符号整数.

(2).u_long htonl(u_longhostlong)

功能:将主机序转化为网络序.

返回:32为无符号整数.

(3).u_short ntohs(u_shortnetshort)

功能:将网络序转化为主机序.

返回:同(1).

(4).u_long ntohl(u_longnetlong)

同上.

 

 3.IP与主机名:

struct hostent *gethostbyname(const char *hostname)

struct hostent {

 char *h_name; \\主机的正式名.

 char *h_aliases;\\主机的别名.

 int h_addrtype; \\主机地址类型.

 int h_length; \\主机的地址长度.

 char **h_addr_list;\\主机的IP地址列表.

};

#define h_addr h_addr_list[0];

 

4.基于TCP----服务器:

  1. 创建一个socket,函数socket();
  2. 制定IP地址,端口等信息到socket上,用函数bind();
  3. 设置允许最大连接数,用函数listen();
  4. 等待客户端请求,函数accept();
  5. 收发数据,send();  recv(); 或  read(); write();
  6. 关闭网络连接;

 

5.基于TCP----客户端:

  1. 创建一个socket,函数socket();
  2. 制定要连接的服务器的IP地址,端口等信息;
  3. 连接服务器,用函数connect();
  4. 收发数据,send();  recv(); 或  read(); write();
  5. 关闭网络连接;

 

相关函数:

intsocket(int af, int type, intprotocal)

af:通信协议的协议族  TCP/IP:AF_INET;

type:SOCK_STREAM:流式套接字.

          SOCK_DGRAM:数据报套接字.

          SOCK_RAM:原始套接字.

protocal:指定应用程序使用的通信协议.

返回:新创建的套接字的描述符.

 

#include<string.h>

voidbzero(void *s, int n)

功能:字符串s,前得n个字节设置为0,包括'\0';

 

#include<sys/types.h>

#include<sys/socket.h>

intbind(int socketfd, const struct sockaddr name,intnamesize)

socketfd:套接口的描述符.从socket()获取.

name:套接口的地址.(赋值)

namesize:name的长度.(sizeof(structsockaddr))

返回:成功返回0,否则返回SOCKET_ERROR(-1);

 

intconnect(int socketfd, struct sockaddr *name, intnamesize)

功能:连接服务器.

同上;

 

int listen(int sockfd,int backlog)

sockfd:套接口的描述符;

backlog:等待连接队列的最大长度;

返回:成功返回0,否则SOCET_ERROR(-1);

 

intaccept(int sockfd, struct sockaddr *name, int*namesize)

功能:等待客户端(阻塞)

sockfd:套接口描述符;

name:套接口地址;

namesize:长度(指针);

例:sin_size =sizeof(struct sockaddr_in)

传入函数的是:&sin_size;

返回:成功返回一个描述接受包的socket类型的值,(类似文件描述符),否则返回INVALID_SOCKET;

 

5.基于UDP----服务器

  1. 创建socket,函数socket();
  2. 绑定IP地址,端口等信息到socket上,用函数bind();
  3. 循环接受数据,用函数recvfrom();
  4. 关闭网络连接;

 

6.基于UDP----客户端

  1. 建socket,函数socket();
  2. 绑定IP地址,端口等信息到socket上,用函数bind();

  3. 设置对方的IP地址和端口等属性;

  4. 发送数据,用函数sendto();

  5. 关闭网络连接;

相关函数:

intrecvfrom(int sockfd, void *buf, int len,intflags, struct sockaddr *from, int*fromlen)

sockfd:套接口标识符;

buf:缓冲区;

len:缓冲区长度;

flags:调用方式;

from(指针):接收源地址的缓冲区;

fromlen(指针):from长度;

返回:成功返回读入的字节数,否则返回0;

 

#include<sys/types.h>

#include<sys/socket.h>

intsendto(int sockfd, char *buf, int len, int flags, const structsockaddr *to, int tolen)

同上;

返回:成功返回读入的字节数,否则返回-1;