SOCKET:套接字

来源:互联网 发布:扬州java后端开发工资 编辑:程序博客网 时间:2024/06/04 04:07

抽象理解:http://www.cnblogs.com/dolphinX/p/3460545.html

SOCKET (domain协议域AF_INET,type类型SOCK_STREAM,protocol协议IPPROTO_TCP)

   说明:套接字,编程接口API,返回【描述符】,失败则-1;描述符在进程空间的【描述符表】,数据结构在内核缓冲里。根据指定的地址族、数据类型和协议来分配一个socket的描述字及其所用的资源。
  
 原理:C发送连接请求→等待连接中的S→接受确认并请求数据;C→wrc;S→rwrc 。
 SOCKET 编程API:
 
 1、绑定:int bind(SOCKET socket描述符,const struct sockaddr *address地址及端口,socketlen_t address_len长度);
       把一个地址族中的特定地址赋给socket。S——启动——bing()——地址——提供服务。C——系统随机生成。
       成功:返回0 ;失败:SOCKET_ERROR;
 2、监听:int listen(int sockfd, int backlog排队的最大连接个数);
 3、connect(int sockfd, const struct sockaddr *addr服务器socket地址, socklen_t addrlen);      
 4、接收:int recv(SOCKET socket描述字, char FAR* buf, int len缓冲区长度, int flags调用方式);
       正常:返回读入字节数;接收中止:返回0;失败:SOCKET_ERROR;
 5、发送:int sendto( SOCKET s套接字, const char FAR* buf, int size, int flags, const struct sockaddr FAR* to, int tolen);
       成功:返回读入字节数;失败:SOCKET_ERROR;
 6、接受连接请求:int accept( int sockfd套接字描述符, struct socketaddr* addr返回连接地址, socklen_t* len);
       成功:返回客户端的文件描述符,失败返回-1。

 应用层:HTTP、FTP、DNS、SMTP、RPC、SNM
 抽象层: Socket
 传输层:TCL、UDP 
 网络层:IP、ICMP、IGMP
 链路层:硬件接口、ARP、RARP

 通信模式: 
 服务端——创建Socket——bing()绑定IP及端口——listen()监听——阻塞——accept()——recv()——close();
 客户端——创建Socket——connect()连接指定端口——send()——close(); 
 C/S循环机制:C_connect().j——S_accept().k——C_send().k+1——S_recv();
 
 一握手:C向S发syn包(syn=j),C进入SYN_SEND;
 二握手:S收syn包并确认k(ack=j+1),S向C发syn包(k),即SYN+ACK,服务器进入recv(); 
 三握手:C收SYN+ACK包,且C向S发确认包ACK(ack=k+1)。
 理解模型[Z字型]:A1发钱包——B1收到签字盖章——A2收到钱包及印章——B2    

 单词: host 主机 、router 路由器 、fiber 光线、Ethernet 以太网、satellite卫星 

C语言实例:服务端:#include<winsock2.h>#include<stdio.h>#pragma comment(lib,"ws2_32.lib")void main(){WSADATA wsaData;SOCKET sockServer;SOCKADDR_IN addrServer; //服务器地址SOCKET sockClient;SOCKADDR_IN addrClient; //客户端地址WSAStartup(MAKEWORD(2,2),&wsaData); //启动命令//bind绑定sockServer=socket(AF_INET,SOCK_STREAM,0);addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//INADDR_ANY表示任何IPaddrServer.sin_family=AF_INET; //2字节地址家族addrServer.sin_port=htons(6000);//绑定端口6000bind(sockServer,(SOCKADDR*)&addrServer,sizeof(SOCKADDR)); //Listen监听端listen(sockServer,5);//5为等待连接数目printf("服务器已启动:\n监听中...\n");int len=sizeof(SOCKADDR); //这个长度有什么用?charsendBuf[100];//发送至客户端的字符串charrecvBuf[100];//接受客户端返回的字符串 //会阻塞进程,直到有客户端连接上来为止sockClient=accept(sockServer,(SOCKADDR*)&addrClient,&len); //接受连接请求//接收并打印客户端数据recv(sockClient,recvBuf,100,0);printf("%s\n",recvBuf); //关闭socketclosesocket(sockClient);WSACleanup();} // 终止Winsock 2 DLL客户端 (Client):#include<winsock2.h>#include<stdio.h>#pragma comment(lib,"ws2_32.lib") //静态库文件void main(){WSADATA wsaData;  //存储WSAStartup函数返回的Windows Sockets数据SOCKET sockClient;//客户端SocketSOCKADDR_IN addrServer;//服务端地址(包含)WSAStartup(MAKEWORD(2,2),&wsaData); //Windows网络编程接口启动命令,在winsock2.h头文件//新建客户端socketsockClient=socket(AF_INET,SOCK_STREAM,0);//定义要连接的服务端地址addrServer.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//目标IP(127.0.0.1是回送地址)addrServer.sin_family=AF_INET;addrServer.sin_port=htons(6000);//连接端口6000//连接到服务端connect(sockClient,(SOCKADDR*)&addrServer,sizeof(SOCKADDR));//发送数据char message[20]="HelloSocket!";send(sockClient,message,strlen(message)+1,0);//关闭socketclosesocket(sockClient);WSACleanup();}/*SOCKADDR结构*/struct sockaddr  {  unsigned short sa_family; /* address family, AF_xxx */  char sa_data[14]; /* 14 bytes of protocol address */  };/*SOCKADDR_IN*/struct sockaddr_in   {  short int sin_family; /* Address family 协议族*/  unsigned short int sin_port; /* Port number 端口号*/  struct in_addr sin_addr; /* Internet address IP地址*/  unsigned char sin_zero[8]; /* Same size as struct sockaddr 为使二者大小相同而保留的空字节*/  };其中in_addr结构的定义如下:typedef struct in_addr {  union {  struct{ unsigned char s_b1,s_b2, s_b3,s_b4;} S_un_b; //四个字节  struct{ unsigned short s_w1, s_w2;} S_un_w; //两个双字节  unsigned long S_addr; //长整型  } S_un;  } IN_ADDR;共用体:三种表示方法,inet_addr函数最简单——addrto.sin_addr.s_addr=inet_addr("192.168.0.2");

0 0