socket 套接字 ---- 记录总结 tool

OSI开放系统互联模型
	应用层		应用程序:FTP、E-mail、Telnet
	表示层		数据格式定义、数据转换/加密
	会话层		建立通信进程的逻辑名字与物理名字之间的联系 
TCP	传输层		差错处理/恢复,流量控制,提供可靠的数据传输	
IP	网络层		数据分组、路由选择
	数据链路层	数据组成可发送、接收的帧
	物理层		传输物理信号、接口、信号形式、速率

TCP/IP协议族 
	应用层		TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 
	传输层		TCP,UDP 
	网络层		IP,ICMP,RIP,OSPF,BGP,IGMP 
	网络接口与物理层	SLIP,CSLIP,PPP,ARP,RARP,MTU ISO2110,IEEE802.1,EEE802.2 

1. 协议
		一组控制数据通信的规则。
		三要素:语法(包括数据格式、编码及信号电平等)、语义(包括用于协议和差错处理的控制信息)、时序(包括速度匹配和排序)。
tcp和udp
	共同点:同为传输层协议

	不同点:
		TCP:有连接,可靠
		UDP:无连接,不保证可靠
	
	TCP(即传输控制协议):
		是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、
		数据无失序、数据无重复到达的通信)

		适用情况:
		适合于对传输质量要求较高,以及传输大量数据的通信。
		在需要可靠数据传输的场合,通常使用TCP协议
		MSN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议

	UDP(User Datagram Protocol)用户数据报协议,是不可靠的无连接的协议。在数据发送前,
		因为不需要进行连接,所以可以进行高效率的数据传输。

	适用情况:
		发送小尺寸数据(如对DNS服务器进行IP地址查询时)
		在接收到数据,给出应答较困难的网络中使用UDP。(如:无线网络)
		适合于广播/组播式通信中。
		MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议
		流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输
Socket
是一个编程接口
是一种特殊的文件描述符 (everything in Unix is a file)
并不仅限于TCP/IP协议

面向连接 (Transmission Control Protocol - TCP/IP)
无连接 (User Datagram Protocol -UDP 和 Inter-network Packet Exchange - IPX)

分类:
流式套接字(SOCK_STREAM)
	提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。
===>TCP
数据报套接字(SOCK_DGRAM)
	提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。
===>UDP
原始套接字(SOCK_RAW)
	可以对较低层次协议如IP、ICMP直接访问。
IP地址
	IP地址是Internet中主机的唯一标识
	Internet中的主机要与别的机器通信必须具有一个IP地址
	IP地址为32位(IPv4)或者128位(IPv6)
	每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由

	表示形式:常用点分十进制形式,如202.38.64.10,最后都会转换为一个32位的无符号整数。
	
	IP地址分类(依据前八位分类)
	A类    0000 0000 - 0111 1111 0.0.0.0 - 127.255.255.255
	B类    1000 0000 - 1011 1111 128.0.0.0 - 191.255.255.255
	C类    1100 0000 - 1101 1111 192.0.0.0 - 223.255.255.255
	D类    1110 0000 - 1110 1111 224.0.0.0 - 239.255.255.255	组播地址
	E类    1111 0000 - 1111 1111 240.0.0.0 - 255.255.255.255	保留测试

	127.x.x.x 表是当前主机地址
	192.168.x.x 表示局域网地址

	子网掩码:标识能够连接主机的最大连接数
		A类		255.0.0.0
		B类		255.255.0.0
		C类		255.255.255.0

 

字节序	
	不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO):
	小端序(little-endian) - 低序字节存储在低地址
	将低字节存储在起始地址,称为“Little-Endian”字节序,Intel、AMD等采用的是这种方式;
	大端序(big-endian)- 高序字节存储在低地址
	将高字节存储在起始地址,称为“Big-Endian”字节序,由ARM、Motorola等所采用
	
	网络中传输的数据必须按网络字节序,即大端字节序
	
	在大部分PC机上,当应用进程将整数送入socket前,需要转化成网络字节序;当应用进程从socket取出整数后,要转化成小端字节序)
	
	如何检测字节序
		方法一:使用指针
		方法二:file命令,其中LSB的L代表小端存储

	将主机字节序转化为网络字节序
    uint32_t htonl(uint32_t hostlong);
    uint16_t htons(uint16_t hostshort);
	
	将网络字节序转化为主机字节序
    uint32_t ntohl(uint32_t netlong);
    uint16_t ntohs(uint16_t netshort);
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>

#define err_log(errmsg) do{\
							perror(errmsg);\
							exit(1);\
						}while(0)

int main(int argc, const char *argv[])
{

	int sockfd;
	struct sockaddr_in serveraddr;
	socklen_t addrlen = sizeof(serveraddr);

	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd == -1)
	{
		perror("fail to socket");
		exit(1);
	}
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(atoi(argv[2]));
	serveraddr.sin_addr.s_addr = inet_addr(argv[1]);

	if(connect(sockfd,(struct sockaddr *)&serveraddr,addrlen) == -1)
	{
		perror("fail to connect");
		exit(1);
	}

	int ret;
	char buf[32] = {};
	while(1)
	{
		fgets(buf,32,stdin);
		buf[strlen(buf) - 1] = '\0';
		ret = send(sockfd,buf,32,0);
		if(ret <= 0)
		{
			err_log("fail to send");
		}
	}
	return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#define err_log(errmsg) do{\
							perror(errmsg);\
							exit(1);\
						}while(0)

int main(int argc, const char *argv[])
{
	int sockfd,acceptfd;
	struct sockaddr_in serveraddr,clientaddr;
	socklen_t addrlen = sizeof(serveraddr);

	//1,创建套接子,也就是说创建双方通信的句柄
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd == -1)
	{
		err_log("fail to socket");
	}
	printf("sockfd:%d\n",sockfd);
	//2.填充地址信息结构体,然后和句柄相绑定
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(atoi(argv[2]));
	serveraddr.sin_addr.s_addr = inet_addr(argv[1]);

	
	int on = 1;
	if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) == -1)
	{
		err_log("fail to setsockopt");
	}
	
	if(bind(sockfd,(struct sockaddr *)&serveraddr,addrlen) == -1)
	{
		perror("fail to bind");
		exit(1);
	}
	//3.将套接子变为监听状态
	if(listen(sockfd,5) == -1)
	{
		perror("fail to listen");
		exit(1);
	}
	while(1)
	{
		if((acceptfd = accept(sockfd,(struct sockaddr *)&clientaddr,&addrlen
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值