tcp/ip 编程之基本概念
来源:互联网 发布:道路工程软件 编辑:程序博客网 时间:2024/06/04 23:30
首先标记别人写的一个较精炼的入门博客:http://blog.csdn.net/chocolate001/article/details/6612201
注:本章笔记对应书籍《TCP/IP高效编程-改善网络程序的44个技巧》 作者:【美】Jon C.Snader
电子版:http://book.51cto.com/art/201104/253696.htm
好了,废话不多说,现在开始我们的学习。
第一章、基本概念
1.面向连接与无连接协议的区别
面向连接:
~使用面向连接的协议就像打电话。
应用程序通常都会进行长期的对话。记住这些状态,协议就可以提供可靠的传输。比如,发送端可以记住哪些数据已经发送出去了但还未被确认,以及数据是什么时候发送的。如果在某段时间间隔内没有收到确认,发送端可以重传数据。接收端可以记住已经收到了哪些数据,并将重复的数据丢弃。如果分组不是按序到达的,接收端可以将其保存下来,直到逻辑上先于它的分组到达为止。
传送数据过程:
第一阶段,在对等实体间建立连接。接下来是数据传输阶段,在这个阶段中,数据在对等实体间传输。最后,当对等实体完成数据传输时,连接被拆除。
可靠协议
无连接:
~使用无连接协议就像寄信。
数据会进行分组,分组被称为数据报。每个数据报都是一个独立的实体,与在两个相同的对等实体之间传送的任何其他数据报都没有关系。网络会尽最大努力传送每一个数据报,但并不保证数据报不丢失、不延迟或者不错序传输。
不可靠协议。
2.子网与CIDR概念
简单说,
子网是因为AB类ip地址主机id部分过长,容易造成浪费。可以利用子网掩码将其中一部分划出作为子网。提高ip地址的利用率。CIDR恰好相反,由于C累地址网络ID部分过长,可容纳主机数量过少。因此利用网络掩码将网络id缩短,一部分用作主机id。
详细概念:http://www.cnblogs.com/nzbbody/p/6389587.html http://blog.csdn.net/dan15188387481/article/details/49873923
3.私有地址与NAT
三块永远不会被分配的保留IP地址。这三个地址块是:
10.0.0.0--10.255.255.255 (前缀10/8);
172.16.0.0--172.31.255.255(前缀172.16/12);
192.168.0.0--192.168.255.255(前缀192.168/16)。
网络使用这三块地址中的任意一块时,网络中的任意一台主机都可以访问此网络中的所有其他主机,而无须担心与全局分配的IP地址产生冲突
但如果网络和外部相连:就要使用NAT NAT负责在私有网络地址和一个或多个全局分配的IP地址之间进行翻译。
详细见:http://book.51cto.com/art/201104/253739.htm
4.开发并使用应用程序框架
socket程序中有很多固定的代码,博主将其修改整理在下面,编写程序时可直接套用。代码均为c语言,但为了结构清晰,用了c++的类结构。windows下 vc6.0亲测通过。
tcp server框架:
#include<winsock2.h>#include <stdio.h>#include <stdlib.h>#pragma comment(lib, "ws2_32.lib") #define DEFAULT_PORT 5051class Server{int iPort;WSADATA wsaData;SOCKET sListen, sAccept;int iLen, iSend;char sendbuf[100];char revcbuf[100];struct sockaddr_in ser, cli;public:int init();void getdata();};int Server::init(){iPort = DEFAULT_PORT;strcpy(sendbuf,"hellow i am a sever");if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){printf("Failed to load Winsock.\n");return 0;}sListen = socket(AF_INET, SOCK_STREAM, 0);if (sListen == INVALID_SOCKET){printf("SOCKET() Failed:%d\n", WSAGetLastError());return 0;}ser.sin_family = AF_INET;ser.sin_port = htons(iPort);ser.sin_addr.S_un.S_addr =htonl(INADDR_ANY); //inet_addr("192.168.1.109") if (bind(sListen, (LPSOCKADDR)&ser, sizeof(ser)) == SOCKET_ERROR){printf("bind() failed:%d\n", WSAGetLastError());return 0;}if (listen(sListen, 5) == SOCKET_ERROR){printf("listen() failed:%d\n", WSAGetLastError);return 0;}iLen = sizeof(cli);return 1;}void Server::getdata(){while (1){sAccept = accept(sListen, (struct sockaddr*)&cli, &iLen);printf("accept");if (sAccept == INVALID_SOCKET){printf("accept failed:%d\n", WSAGetLastError());break;}printf("Accept client IP:[%s],port:[%d] \n", inet_ntoa(cli.sin_addr), ntohs(cli.sin_port));iSend = send(sAccept, sendbuf, sizeof(sendbuf), 0);if (iSend == SOCKET_ERROR){printf("send() failed:%d\n", WSAGetLastError());break;}while(1){int k=recv(sAccept,revcbuf,sizeof(revcbuf), 0);if(k<=0)break;if(strcmp(revcbuf,"end")!=0)printf("%s\n",revcbuf);//inet_ntoa(cli.sin_addr)}printf("client shutdown\n");printf(".............");printf("Sever waitting\n");closesocket(sAccept);}}void main(){Server ser;if(ser.init()==0){printf(".............");printf("Sever init error\n");}printf(".............");printf("Sever waitting\n");ser.getdata();}
tcp client框架:
#include <WinSock2.h>#include <stdio.h>#pragma comment(lib, "ws2_32.lib")#define DEFAULE_PORT 5051#define DATA_BUFFER 1024class Client{WSADATA wsaData;SOCKET sClient;int iPort;INT iLen;char sendbuf[100];char recvbuf[100];struct sockaddr_in ser;public:int init(char *argv[]);void senddata();void close();};int Client::init(char *argv[]){iPort = DEFAULE_PORT;memset(recvbuf, 0, sizeof(recvbuf));if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){printf("Failed to load Winsock.\n");return 0;}ser.sin_family = AF_INET;ser.sin_port = htons(iPort);ser.sin_addr.S_un.S_addr = inet_addr(argv[1]);sClient = socket(AF_INET, SOCK_STREAM, 0);if (sClient == INVALID_SOCKET){printf("socket() Failed :%d\n", WSAGetLastError());return 0;}return 1;}void Client::senddata(){if (connect(sClient, (struct sockaddr*)&ser, sizeof(ser)) == INVALID_SOCKET){printf("connect() Failed :%d\n", WSAGetLastError());return;}else{iLen = recv(sClient, recvbuf, sizeof(recvbuf), 0);if (iLen == 0)return;else if (iLen == SOCKET_ERROR){printf("recv() Failed :%d\n", WSAGetLastError());return;}printf("recv() data from server:%s\n", recvbuf);while(1){sendbuf[0]='\0';printf("myname:\n");while(sendbuf[0]=='\0'){gets(sendbuf);}if(strcmp(sendbuf,"end")==0)break;send(sClient,sendbuf,sizeof(sendbuf),0);}}}void Client::close(){closesocket(sClient);WSACleanup();system("pause");}void main(int argc, char *argv[]){if (argc < 2){printf("Usage :client[server IP address]\n");return;}Client cli;if(cli.init(argv)==0)printf("init fail()");cli.senddata();cli.close();}
UDP server框架
#include<winsock2.h>#include <stdio.h>#include <stdlib.h>#pragma comment(lib, "ws2_32.lib") #define DEFAULT_PORT 5050 //定义通信端口号#define BUFFER_LENGTH 1024 //传输数据缓冲大小class Server{int iPort;WSADATA wsaData;//这个结构被用来存储被WSAStartup函数调用后返回的Windows Sockets数据SOCKET sSocket;int iLen, iSend,iRecv;//客户地址,发送数据,接受数据长度char recv_buf[BUFFER_LENGTH];//接受字符串struct sockaddr_in ser, cli;public :int init();void getdata();void close();};int Server::init(){iPort=DEFAULT_PORT;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){printf("Failed to load Winsock.\n");return 0;}//sScoket初始化并绑定自身信息sSocket = socket(AF_INET, SOCK_DGRAM, 0);if (sSocket == INVALID_SOCKET){printf("SOCKET() Failed:%d\n", WSAGetLastError());return 0;}ser.sin_family = AF_INET;ser.sin_port = htons(iPort);ser.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//inet_addr("192.168.1.109")if (bind(sSocket, (LPSOCKADDR)&ser, sizeof(ser)) == SOCKET_ERROR){printf("bind() failed:%d\n", WSAGetLastError());return 0;}iLen = sizeof(cli);memset(recv_buf,0,sizeof(recv_buf));//将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值return 1;}void Server::getdata(){while (1){iRecv=recvfrom(sSocket,recv_buf,BUFFER_LENGTH,0,(SOCKADDR*)&cli,&iLen);if (iRecv==SOCKET_ERROR){printf("recvfrom() failed:%d\n", WSAGetLastError());break;}else if(iRecv==0)break;else{printf("Accept client IP:[%s],port:[%d] \n", inet_ntoa(cli.sin_addr), ntohs(cli.sin_port));printf("%s\n",recv_buf);}}}void Server::close(){closesocket(sSocket);WSACleanup();}void main(){Server ser;if(ser.init()==0){printf(".........................\n");printf("Server start error\n");printf(".........................\n");}printf(".........................\n");printf("Sever waitting\n");printf(".........................\n");ser.getdata();ser.close();}
udp client框架
#include <WinSock2.h>#include <stdio.h>#pragma comment(lib, "ws2_32.lib")#define DEFAULE_PORT 5050#define DATA_BUFFER 1024class Client{WSADATA wsaData;SOCKET sClient;int iPort;int iLen,iSend;char send_buf[DATA_BUFFER];struct sockaddr_in ser;public:int init(char *argv[]);void senddata();void close();};int Client::init(char *argv[]){iPort=DEFAULE_PORT;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){printf("Failed to load Winsock.\n");return 0;}ser.sin_family = AF_INET;ser.sin_port = htons(iPort);ser.sin_addr.S_un.S_addr = inet_addr(argv[1]);//sClient = socket(AF_INET, SOCK_DGRAM, 0);if (sClient == INVALID_SOCKET){printf("socket() Failed :%d\n", WSAGetLastError());return 0;}iLen=sizeof(ser);return 1;}void Client::senddata(){while(1){send_buf[0]='\0';printf("myname:\n");while(send_buf[0]=='\0'){gets(send_buf);}iSend=sendto(sClient,send_buf,sizeof(send_buf),0,(struct sockaddr*)&ser,iLen);if(strcmp(send_buf,"end")==0)break;if (iSend == SOCKET_ERROR){printf("send() failed:%d\n", WSAGetLastError());return;}else if(iSend==0)return;}}void Client::close(){closesocket(sClient);WSACleanup();}void main(int argc, char *argv[]){if (argc < 2){printf("Usage :client[server IP address]\n");return;}Client cli;cli.init(argv);cli.senddata();cli.close();}
5.Tcp是一种流协议
TCP是一种流协议(stream protocol),这意味着数据是以字节流的形式发给接收者的,没有固定的报文和报文边界的概念。接收端读取tcp数据,无法预知在这一次读操作中会返回多少个字节。
详细内容请阅读:http://book.51cto.com/art/201104/253755.htm
对于材料中的几点理解:
1.readn()函数:接收定长报文,由于任意一次读操作返回的数据量不可预测,可将一次读取分为多次读取,cnt标记剩余未读取字节数,rc记录本次读取字节长度。
2.readvrec()函数:接收变长报文,reclen:读入记录长度,根据缓冲区是否能装下整条记录分成两种情况。
- tcp/ip 编程之基本概念
- TCP/IP学习之基本概念
- TCP/IP编程之四书五经
- TCP/IP编程之四书五经
- TCP/IP编程之四书五经
- TCP/IP 基本概念
- tcp/ip基本概念
- TCP/IP(1)基本概念
- TCP/IP(1)-基本概念
- TCP/IP详解--基本概念
- TCP/IP协议基本概念
- TCP/IP网络编程之TCP
- TCP/IP网络编程之TCP
- 网络编程的基本概念,TCP/IP协议简介
- Linux网络编程之tcp/ip编程
- 网络:基本概念之HTTP、TCP/IP、UDP,Socket
- 【Linux基础】TCP/IP基本概念
- Winsocket编程之TCP/IP体系结构
- android如何同时控制EditText输入字符个数和禁止特殊字符输入?
- java11
- MyBatis整合Spring相关错误
- 对象与对象引用---2种相似的解释(以java为例)
- 索引高效排序法,10000长度随机数组排序 200毫秒
- tcp/ip 编程之基本概念
- Java中的关键字
- HTML知识续
- window下配置mysql远程访问
- NAT穿透的详细讲解及分析
- Effective Java读书笔记十七(Java Tips.Day.17)
- XT邀请赛赛后总结
- H264视频压缩编码标准(一)
- 抽象类和接口