本文为自己的学习总结,没有那些大神们那么的深入,只为自己的一些心得总结,有很多不足之处,请各位勿喷,望多多指正!!无限感激
一、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 \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 \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 \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 \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;
}