网络编程,TCP协议

一、网络编程学习大纲。
1、网络体系结构模型。
2、网络编程专业术语:socket、IP地址、端口号。
3、配置ubuntu系统IP地址。
4、通信协议:TCP协议、UDP协议。
5、网络编程IO模型: 阻塞IO、非阻塞IO、多路复用、信号驱动。
6、超时接收数据方式。

二、网络编程专业术语。
1、系统编程中进程之间通信与网络编程有什么区别?
网络编程其实也是属于进程之间的通信。
系统编程进程之间通信:管道通信,信号,消息队列,共享内存,他们的特点可以实现同一台主机内部的两个任意的进程之间的通信。
网络编程可以作用于同一个主机/跨主机的两个任意的进程。

2、网络体系结构模型。
只要主机能够进行网络通信,主机内部就会有这个结构模型。

OSI模型(7层)
1)应用层    -> 老板想说的话。
2)表示层    -> 秘书将老板想说的话写成一封信。
3)会话层    -> 前台将信塞到信封里面,然后在信封上写上对方的地址。
4)传输层    -> 邮差会想:待会我选择什么方式去送信   -> 公交/地铁?   -> TCP协议、UDP协议
5)网络层    -> 邮差分析地址在哪里                                   -> IP协议
6)数据链路层-> 邮差选择一条正确线路进行传输
7)物理层    -> 出发!                                               -> 网卡、网口、网线。

TCP/IP协议模型(4层)
1)应用层    -> 老板把自己想说的话,写入到一封信中,然后写上对方的地址,并塞到信箱中。
2)传输层    -> 邮差会想:待会我选择什么方式去送信   -> 公交/地铁?   -> TCP协议、UDP协议
3)网络层    -> 邮差分析地址在哪里                     -> IP协议 
4)网络接口与物理层    -> 选择一条正确的路线后出发。

3、什么是socket?
1)socket在英文中翻译为套接字,插座,排插。(因为插座种类非常多,就好像有很多协议一样,这些协议必须一致,才可以进行通信。)
网络编程  -> 套接字编程、socket编程。

2)socket()其实也是一个函数接口。  
   该函数功能: 就是创建一个套接字。

3)socket也指套接字  -> 特殊的文件描述符。

4、什么是IP地址?
例如: 192.168.14.2   -> 点分制
在一个局域网中,每一台主机都会有一个IP地址,而且IP地址必须是相同的网段   -> 指的是IP地址前3个数字一样。
每一个IP地址都是32位。 如果在网络编程的代码中使用到IP地址,那么就必须把这32位的数据转成网络字节。

5、什么是端口号?
在一个局域网中,两台主机需要通信,除了IP地址需要处于同一个网段中,还需要使用相同的端口号。

                      主机A              主机B 
 IP地址相同网段:  192.168.14.2      192.168.14.4
  相同的端口号:      5000               5000

端口号是16位。  如果在网络编程的代码中使用到端口号,那么就必须把这16位的数据转成网络字节。
系统用了端口: 0~1023     (用户不能使用)
用户有效端口: 1024~65535 (用户随便用)  -> 端口号使用结束后,至少等待1分钟之后,才能再次使用。

三、配置ubuntu系统IP地址。
0. 启用网卡。
gec@ubuntu:~$ sudo ifconfig ens33 up

1、以老关IP地址为例子。

192.168.14.2  -> 老关的电脑。
192.168.14.3  -> 老关的开发板。
192.168.14.4  -> 老关的ubuntuIP地址。

2、查看当前ubuntu的IP地址。
gec@ubuntu:/mnt/hgfs/GZ2057/09 系统编程/08/thread_pool/pool_test$ ifconfig
网卡名字
ens33     Link encap:Ethernet  HWaddr 00:0c:29:47:5e:0a  
          inet addr:192.168.14.18    -> 当前ubuntu的IP地址

3、临时配置ubuntuIP地址。
gec@ubuntu:/mnt/hgfs/GZ2057/09 系统编程/08/thread_pool/pool_test$ sudo ifconfig ens33 192.168.14.4
[sudo] password for gec: 

(重启终端无效) 

4、修改IP地址配置文件的权限。
gec@ubuntu:~$ sudo chmod 777 /etc/network/interfaces

5、如果需要永久配置,则需要打开一个IP地址配置文件:
gec@ubuntu:~$ vi /etc/network/interfaces  

   # interfaces(5) file used by ifup(8) and ifdown(8)
   auto lo
   iface lo inet loopback
   
   ------------------------------ 补充以下的内容即可  ------------------
   auto ens33
   iface ens33 inet static
   
   address 192.168.14.x    -> 记得用自己的。
   netmask 255.255.255.0
   gateway 192.168.14.1      
   -------------------------------

输入完之后,记得保存退出。

6、 重启虚拟机。

四、通信协议。  ---  TCP协议。
1、TCP协议特点?
TCP协议全称: Tranmission Control Protocol
        传输       控制    协议

TCP协议通信类似于现实打电话,必须要连接上才能通信。   -> TCP协议是一种可靠的传输方式。
TCP协议作用场景: 账号登录,文件传输。

2、 分析TCP协议原理。
TCP协议能够正常连接,原因是双方遵循三次握手协议。
1)第一次握手:
在建立TCP连接时,客户端发送syn包(seq=j)给服务器,客户端等待服务器确认。

2)第二次握手:
服务器收到了syn包之后,必须确认客户端的SYN(ack=j+1),同时服务器也会发送一个SYN包(seq=k)给客户端,即SYN+ACK,此时服务器进入等待状态。

3)第三次握手:
客户端收到服务器发过来的SYN+ACK包,想服务器发送确认包(ACK=k+1),此包发送完毕,客户端与服务器就连接上了。

3、 示例。
发送端:
#include "head.h"

int main(int argc,char *argv[])  // ./rose 50000
{
    //1. 创建TCP套接字
    int sockfd;
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    printf("sockfd = %d\n",sockfd);
    
    //2. 绑定IP地址,端口号
    struct sockaddr_in srvaddr;
    socklen_t len = sizeof(srvaddr);
    bzero(&srvaddr,len);
    
    srvaddr.sin_family = AF_INET;  //地址族
    srvaddr.sin_port = htons(atoi(argv[1]));  //端口号
    srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址  /usr/include/linux/in.h
    
    bind(sockfd,(struct sockaddr *)&srvaddr,len);
    
    //3. 设置监听套接字
    //调用listen之前: sockfd -> 待连接的套接字
    listen(sockfd,5);
    //调用listen之后: sockfd -> 监听套接字
    
    //4. 等待客户端的连接
    struct sockaddr_in cliaddr;
    int connfd;
    
    connfd = accept(sockfd,(struct sockaddr *)&cliaddr,&len);
    if(connfd >= 0)
    {
        printf("connfd = %d\n",connfd);
        printf("new connection:%s\n",inet_ntoa(cliaddr.sin_addr));
    }
    
    //5. 读取套接字上的数据
    char buf[100];
    while(1)
    {
        bzero(buf,sizeof(buf));
        recv(connfd,buf,sizeof(buf),0);
        printf("from jack:%s",buf);
        
        if(strncmp(buf,"fenshou",7) == 0)
        {
            break;
        }
    }
    
    //6. 回收TCP套接字的资源
    close(sockfd);
    close(connfd);
    
    return 0;    
}

接收端:
#include "head.h"

int main(int argc,char *argv[])  // ./jack 192.168.14.4 50000
{
    //1. 创建TCP套接字
    int sockfd;
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    printf("sockfd = %d\n",sockfd);
    
    //2. 准备rose的IP地址。
    struct sockaddr_in srvaddr;
    socklen_t len = sizeof(srvaddr);
    bzero(&srvaddr,len);
    
    srvaddr.sin_family = AF_INET;  //地址族
    srvaddr.sin_port = htons(atoi(argv[2]));  //端口号
    inet_pton(AF_INET,argv[1],&srvaddr.sin_addr); //设置好Rose的IP地址
    
    
    //3. 发起连接
    //connect调用之前: sockfd  -> 待连接套接字
    int ret = connect(sockfd,(struct sockaddr *)&srvaddr,len);
    if(ret > 0)
    {
        printf("connect success!\n");
    }
    //connect调用之后: sockfd  -> 已连接套接字
    
    //4. 发送数据给rose
    char buf[100];
    
    while(1)
    {
        bzero(buf,sizeof(buf));
        fgets(buf,sizeof(buf),stdin);
        
        send(sockfd,buf,strlen(buf),0);
        if(strncmp(buf,"fenshou",7) == 0)
        {
            break;
        }
    }
    
    //5. 回收TCP套接字的资源
    close(sockfd);
    
    return 0;
}

 作业1: 尝试使用老关的代码试试能不能通信。   自己与自己的ubuntu通信。
 作业2: 自己的ubuntu与自己的开发板通信。
     自己的ubuntu与同桌的ubuntu通信。
     自己的开发板与同桌的ubuntu通信。
     自己的开发板与同桌的开发板通信。

 作业3: 修改代码,实现客户端与服务器互相收发。
 作业4: 写一个回射服务器,客户端发送了什么数据给服务器,服务器就会回发什么数据给客户端。
 作业5: 去看昨晚的project代码。

      


                              
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值