TCP/IP协议学习总结

来源:互联网 发布:双赢物流软件下载 编辑:程序博客网 时间:2024/06/05 03:52

本文为自己的学习总结,没有那些大神们那么的深入,只为自己的一些心得总结,有很多不足之处,请各位勿喷,望多多指正!!无限感激


一、TCP/IP协议

为什么会有这个协议: 为了实现不同计算机系统/网络系统之间的通信其他还有很多网路协议,只是很多只能特定某些计算机系统间的通信,通用性不强
TCP/IP协议是什么: IP协议: 实现不同网路的互联; TCP: 用于传输控制协议

TCP/IP协议的体系结构: 主要有四个层次:应用层(我们的数据)、传输层(TCP/UDP,实现传输数据)、网络层(IP层,实现不同网路之间的链接,包括如何
                                      找到目标机器)、网路接口和物理层(实现真正的数据发送)。

接下来深入理解这几个协议:
       实现网路互联的协议(IP协议): 最主要的就是通过IP地址找到目标机器。IP地址有四类(A、B、C、D)
                                                     A类:  1.0.0.1 ~ 127.255.255.255
                                                     B类:  128.0.0.1 ~ 191.255.55.255
                                                     C类:  192.0.0.1 ~ 223.255.255.255
                                                     D类:  224.0.0.1~ 239.255.255.255 (用于组播)
      实现数据传播的协议:
             TCP协议(传输控制协议): 必须先建立连接然后才能通信(相当于打电话,必须得到应答只有才能通信,而且有数据检验),可靠性高。
             UDP协议(数据报文传输协议): 不可靠无连接传输(只管发送出去,相当于写信,对方收不收到都不管),传输快,但是不可靠常用于广播 。

二、如何进行网络编程(Linux)
Socket:进程通信接口、网路通信编程接口,不仅适用于本地进程的通信, 还适用于网路之间进程的通信。
          面向连接的 Socket机制与国家电话网路有点类似:两个电话号码相当于两个进程Socket号。电话的区号相当于一个网路地址,区内的一个单位交换机相当于一台电脑主机,区内的每一个电话(号码)相当于进程的Socket号。用户打电话通信前都需要有一个号码,也就是两个进程通信前要有一个Socket号。拨打电话的时候相当于通过Socket号进行连接,如果对方不在用一个区域那么就得加上区号也相当于网路地址(IP地址)。若果对方电话机存在并且空闲,那么就进行通信,想电话机发出信息或者接收信息,就相当于像Socket发出信息或者接收信息。我们在通过电话通信的时候,电话机是屏蔽了整个电话系统里面的东西(比如怎么进行组网呀,怎么进行查找某个电话机呀等等),而Socket也是屏蔽了整个互联网的细节(比如如何查找到某个主机,如何建立连接等等),这样的话,给应用层编程带来了很多的方便之处。

Socket编程的注意事项: IP地址的绑定、端口号的绑定、字节序(网路字节序为大端序)、防火墙、超时等问题

Socket有三种类型,分别用于不同的协议:  
            流式套接字(SOCK_STREAM): 适用于 TCP协议
            数据报套接字(SOCK_DGRAM): 适用于UDP协议
            原始套接字(SOCK_RAM): 可以直接访问 IP、ICMP层

网络编程常用接口函数:
socket(): 创建套接字
bind(): 绑定本机地址和端口
connect(): 建立连接(用于TCP客户端)
listen(): 监听套接字
accept(): 接受TCP连接(用于TCP服务器)
recv()、read()、recvfrom() : 接收数据,其中recvfrome()用于UDP协议
send()、write()、sendto(): 发送数据,其中 sendto() 用于UDP协议
close()、shutdown() : 关闭套接字

常用结构体:
struct sockaddr        //通用地址结构体
{
    u_short sa_family;  //地址簇, AF_xxx
    char sa_data[14];  //十四字节协议地址
}

struct sockaddr_in      // Internet 协议地址结构体
{
    u_short sin_family;    // 地址簇, AF_xxx
    u_short sin_port;      //端口
    struct in_addr sin_addr;  //IPV4地址
    char sin_zero[8];
}

编程的总体思想是:寻找目标主机、寻找目标进程、通信
TCP编程流程:  

例子:
服务器端
#include "head_net.h"
int main(int argc,char **argv)
{
    int sock_fd,conn_fd;
    struct sockaddr_in sin,cin;
    socklen_t len;
    char cli_ip[16];
    char buf[SIZE];
    int ret;

    if(argc != 2){
fprintf(stderr,"Usage %s <SRV_IP>\n",argv[0]);
exit(1);
    }

    /*1:创建socket*/
    if( (sock_fd = socket(AF_INET,SOCK_STREAM,0)) < 0) 
     p_error("socket");

    /*2:绑定地址*/
    bzero(&sin,sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
    sin.sin_addr.s_addr = inet_addr(SRV_IP);
    if(bind(sock_fd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
p_error("bind");

    /*3:监听*/
    if(listen(sock_fd,N) < 0)
p_error("listen");

    /*4:连接,三次握手*/
    if( (conn_fd = accept(sock_fd,(struct sockaddr*)&cin,&len))<0)
p_error("accept");

    /*5:通信*/
    while(1){
bzero(buf,SIZE);
if( (ret = read(conn_fd,buf,SIZE)) < 0)
    p_error("read");
else if(0 == ret){
    close(sock_fd);
    break;
}
if(strncmp(buf,"quit",4) == 0)
    break;
printf("%s",,buf);
    }    
    /*6:关闭socket*/
    shutdown(conn_fd,0);
    return 0;
}

客户端:
#include "head_net.h"
int main(int argc,char **argv)
{
    int sock_fd;
    struct sockaddr_in sin;
    char buf[SIZE];

    if(argc != 2){
fprintf(stderr,"Udage %s <des_ip>\n",argv[0]);
exit(1);
    }

    if( (sock_fd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
p_error("socket");

    bzero(&sin,sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
    sin.sin_addr.s_addr = inet_addr(argv[1]);

    while(1){
bzero(buf,SIZE);
fgets(buf,SIZE,stdin);
buf[strlen(buf)-1] = '\0';
sendto(sock_fd,buf,strlen(buf),0,(struct sockaddr*)&sin,sizeof(sin));
if(strncmp(buf,"quit",4)! == 0)
    break;
    }
    
    close(sock_fd);
    return 0;
}


UDP编程流程:

例子:
服务器
#include "head_net.h"
int main(int argc,char **argv)
{
    int sock_fd;
    struct sockaddr_in sin,cin;
    char buf[SIZE];
    char cli_ip[16];
    socklen_t len;

    if(argc != 2){
fprintf(stderr,"Udage %s <des_ip>\n",argv[0]);
exit(1);
    }

    if( (sock_fd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
p_error("socket");

    bzero(&sin,sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
    sin.sin_addr.s_addr = inet_addr(argv[1]);

    if(bind(sock_fd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
p_error("bind");
    len = sizeof(cin);
    while(1){
bzero(buf,SIZE);
recvfrom(sock_fd,buf,SIZE,0,(struct sockaddr*)&cin,&len);
if(strncmp(buf,"quit",4) == 0)
    break;
strcpy(cli_ip,inet_ntoa(cin.sin_addr));
printf("%s from %s\n",buf,cli_ip);
    }
    
    close(sock_fd);
    return 0;
}

客户端:
#include "head_net.h"

int main(int argc,char **argv)
{
    int sock_fd;
    struct sockaddr_in sin;
    char buf[SIZE];

    if(argc != 2){
fprintf(stderr,"Udage %s <des_ip>\n",argv[0]);
exit(1);
    }

    if( (sock_fd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
p_error("socket");

    bzero(&sin,sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
    sin.sin_addr.s_addr = inet_addr(argv[1]);

    while(1){
bzero(buf,SIZE);
fgets(buf,SIZE,stdin);
buf[strlen(buf)-1] = '\0';
sendto(sock_fd,buf,strlen(buf),0,(struct sockaddr*)&sin,sizeof(sin));
if(strncmp(buf,"quit",4)! == 0)
    break;
    }

    close(sock_fd);
    return 0;
}



























0 0
原创粉丝点击