TCP/UDP网络编程
2016-03-16 16:21
555 查看
TCP/UDP网络编程
sf2gis@163.com
2012年2月07日
Port:用于标识系统中每个应用的标识号;IPV4:32位,4个字节组成;
IP与Port组合在一起可以确定一个唯一的应用;
协议:是用来规定通信双方的数据规则的.
对等通信:虚拟通信,下层对上层单向提供服务;
封装:按照特定的协议将数据加入协议头(有的包含协定尾)的数据打包过程称为封装;
PDU:protocol data unit,协议数据单元,指的是对等层之间交换的数据包.
TCP提出了协议端口(protocolport,简称端口):为了标识通信实体中进行通信的进程(应用),指定一个数字作为标识,从而使两个通信进程之间交换数据,称之为端口;
后门:强制控制计算机打开某个端口进行通信,就是后门程序,也就是木马;
0~1024:系统预定义端口;(http:80,telnet:23,ftp:21,SMTP:25,pop3:110)
1025~49151:用于软件注册的端口;
49151~65535:用于动态/私有端口(易为木马等使用);
windows socket只支持网际域的通信区域;
V1.1与Unix Berkeley Socket通用性强,易移植;
有三种类型的SOCKET:
SOCK_STREAM:TCP;
SOCK_DGRAM:UDP:
SOCK_RAW:原始SOCKET;
UDP:无连接的,实时性强,不能保证数据的完整性;
客户端只需指定服务器地址,并将此地址连接到本地Socket上,就可以进行数据收发.
wVersionRequest:要求的库版本号(高位为副版本号,低位为主版本号);
wsaData:加载的库信息;
成功后返回0,否则返回错误码;
使用WSAStartup()成功加载后,应用WSACleanup()进行资源释放;
//加载Socket DLL
WORDwVersionRequest;
WSADatawsaData;
int err;
wVersionRequest=MAKEWORD(1,1);//生成(高位,低位)WORD
err=WSAStartup(wVersionRequest,&wsaData);
if(err!=0)//如果成功调用,则返回
{
return;
}
if(LOBYTE(wsaData.wVersion)!=1||LOBYTE(wsaData.wVersion)!=1)//高位代表副版本,低位代表主版本
{
WSACleanup();//如果WSAStartup()成功调用DLL后,则应使用WSACleanup()释放资源
return;
}
//创建SOCKET
SOCKETsockSrv=socket(AF_INET,SOCK_STREAM,0);//推荐指定协议类型为,则根据地址格式和Socket类型自动判断
if(sockSrv==INVALID_SOCKET)
{
if(WSAEMFILE==WSAGetLastError());//返回错误码,可以据此判断错误类型
{
printf("No more socket descriptors are available\n");
}
return;
}
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
printf("bind...\n");
listen(sockSrv,5);
printf("listen...\n");
intlen=sizeof(SOCKADDR);
while(1)
{
…
}
SOCKETsockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
charsendBuf[100];
sprintf(sendBuf,"SendBuf %s is here.",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
//接收(可以持续接收客户端发送的数据)
while(1)
{
charreceiveBuf[100];
recv(sockConn,receiveBuf,100,0);
printf("%s\n",receiveBuf);
}
closesocket(sockConn);
closesocket(sockSrv);
WSAData wsaData;
wVersionRequset=MAKEWORD(1,1);
int err=WSAStartup(wVersionRequest,&wsaData);
if(err!=0)
{
return;
}
if(LOBYTE(wVersionRequest)!=1||HIBYTE(wVersionRequest)!=1)
{
WSACleanup();
return;
}
addrSrv.sin_family=AF_INET;
addSrv.sin_port=htons(6000);
addSrv.sin_addr.S_un.S_addr=inet_addr(“192.186.1.161”);
connect(sockClient,(SOCKADDR*)(&addrSrv ),sizeof(addrSrv));
send(sockClient,sendBuf,strlen(sendBuf)+1,0);
char recvBuf=[100];
recv(sockClient,recvBuf,100,0);
WSAData wsaData;
int err;
wVersionRequest=MAKEWORD(1,1);
err=WSAStartup(wVersionRequest,&wsaData);
if(err!=0)
{
return;
}
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
{
WSACleanup();
return;
}
if(sockSrv ==INVALID_SOCKET)
{
return;
}
addrSrv.sin_family=AF_INET;
addrSrv.sin_addr.S_un.S_addr=htonl(ADDR_ANY);
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)(&addrSrv),sizeof(SOCKADDR));
int len=sizeof(SOCKADDR);
SOCKADDR_IN addrClient;
recvfrom(sockSrv,recvBuf,100,0,(SOCKETADDR*)(*addrClient),&len);
char* sendBuf=”this is from server.”;
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKETADDR*)(&addrClient),len);
WSAData wsaData;
int err;
wVersionRequest=MAKEWORD(1,1);
err=WSAStartup(wVersionRequest,&wsaData);
if(err!=0)
{
return;
}
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
{
WSACleanup();
return;
}
if(sockClient ==INVALID_SOCKET)
{
return;
}
addrSrv.sin_family=AF_INET;
addSrv.sin_port=htons(6000);
addSrv.sin_addr.S_un.S_addr=inet_addr(“192.168.1.161”);
int len=sizeof(SOCKADDR);
char* sendBuf=”this is from client.”;
sendto(sockClient,sendBuf,sizeof(sendBuf)+1,0,(SOCKADDR*)(&addrSrv),len);
char recvBuf[100];
recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)(&addrSrv),&len);
FTP:QFtp;
Http:QNetworkAccessManager,QtNetworkReply;(QHttp类的替代);
本机信息:QHostInfo;
TCP:QTcpServer,QTcpSocket;
UDP:QUdpSocket;
代理:QNetworkProxy;
加密:QSslSocket;
使用时要添加Network模块,并包含QtNetwork模块;
QNetworkReply:HttpReply的具体类实现,作为请求的响应,由QNetworkAccessManager返回;以串行化形式返回获得的数据;如果获得数据,就会发出readyRead()信号和downloadProgress()信号(可以不准);如果数据接收完成,就会发出finished()信号;
QNetworkRequest:HttpRequest的具体类实现;作为请求,由QNetworkAccessManager发出;
QNetworkReqest request(url);
sf2gis@163.com
2012年2月07日
1 概述
1.1 IP,Port与Protocol
IP:网络上每个主机的唯一标识号Port:用于标识系统中每个应用的标识号;IPV4:32位,4个字节组成;
IP与Port组合在一起可以确定一个唯一的应用;
协议:是用来规定通信双方的数据规则的.
1.2 ISO/OSI七层模型:
应用层->表示层->会话层->传输层->网络层->数据链路层->物理层对等通信:虚拟通信,下层对上层单向提供服务;
封装:按照特定的协议将数据加入协议头(有的包含协定尾)的数据打包过程称为封装;
PDU:protocol data unit,协议数据单元,指的是对等层之间交换的数据包.
1.3 TCP/IP模型:
应用层->传输层->网络层->网络接口层TCP提出了协议端口(protocolport,简称端口):为了标识通信实体中进行通信的进程(应用),指定一个数字作为标识,从而使两个通信进程之间交换数据,称之为端口;
后门:强制控制计算机打开某个端口进行通信,就是后门程序,也就是木马;
0~1024:系统预定义端口;(http:80,telnet:23,ftp:21,SMTP:25,pop3:110)
1025~49151:用于软件注册的端口;
49151~65535:用于动态/私有端口(易为木马等使用);
1.4 socket:
socket:最初由berkeley大学发布的一种用于应用程序调用通信协议的对象;它将通信协议中使用的共有特性进行封装以进行方便通信过程.windows socket只支持网际域的通信区域;
1.5 网络字节顺序:
不同的计算机对字节的存储顺序可能有所不同,起始地址有的以高位存储,有的以低位存储;网络传输时,规定了固定的存储方式,因此在使用网络传输时,应使用htos(),htol()方法将本地存储内容转换为网络存储格式;1.6 WindowsSocket:
从Berkeley Socket发展而来,以DLL形式提供;以WSAStartup()加载(windows socket api);在winXp中为ws2_32.dll,ws2_32.lib,Winsock2.hV1.1与Unix Berkeley Socket通用性强,易移植;
有三种类型的SOCKET:
SOCK_STREAM:TCP;
SOCK_DGRAM:UDP:
SOCK_RAW:原始SOCKET;
1.7 TCP/UDP
TCP:而向连接的,有数据重发和数据校验功能;实现性弱,数据完整性高;UDP:无连接的,实时性强,不能保证数据的完整性;
1.8 服务器与客户端差别
服务器端需要将服务器的地址端口信息绑定到指定的Socket上,此Socket监听指定IP的指定Port.TCP会在有连接请求时,建立连接,并将连接地址生成一个新的Socket.在此Socket上,进行面向连接的数据收发.UDP是无连接的,可以直接进行数据收发.客户端只需指定服务器地址,并将此地址连接到本地Socket上,就可以进行数据收发.
2 TCP编程
2.1 TCP服务器端编程
2.1.1 加载Windows Socket DLL
使用WSAStartup(wVersionRequest,&wsaData);加载指定的WSDLL;wVersionRequest:要求的库版本号(高位为副版本号,低位为主版本号);
wsaData:加载的库信息;
成功后返回0,否则返回错误码;
使用WSAStartup()成功加载后,应用WSACleanup()进行资源释放;
//加载Socket DLL
WORDwVersionRequest;
WSADatawsaData;
int err;
wVersionRequest=MAKEWORD(1,1);//生成(高位,低位)WORD
err=WSAStartup(wVersionRequest,&wsaData);
if(err!=0)//如果成功调用,则返回
{
return;
}
if(LOBYTE(wsaData.wVersion)!=1||LOBYTE(wsaData.wVersion)!=1)//高位代表副版本,低位代表主版本
{
WSACleanup();//如果WSAStartup()成功调用DLL后,则应使用WSACleanup()释放资源
return;
}
2.1.2 创建 SOCKET
使用socket()函数进行创建;成功返回socket,错误返回INVALID_SOCKET;使用WSAGetLastError()获取错误码;//创建SOCKET
SOCKETsockSrv=socket(AF_INET,SOCK_STREAM,0);//推荐指定协议类型为,则根据地址格式和Socket类型自动判断
if(sockSrv==INVALID_SOCKET)
{
if(WSAEMFILE==WSAGetLastError());//返回错误码,可以据此判断错误类型
{
printf("No more socket descriptors are available\n");
}
return;
}
2.1.3 绑定SOCKET
//绑定SOCKETSOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
printf("bind...\n");
2.1.4 监听SOCKET
//监听listen(sockSrv,5);
printf("listen...\n");
2.1.5 循环等待用户请求;
SOCKADDR_IN addrClient;intlen=sizeof(SOCKADDR);
while(1)
{
…
}
2.1.6 接受连接请求,并返回连接SOCKET
//接受连接请求SOCKETsockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
2.1.7 以连接SOCKET进行数据收(recv)发(send)
//发送(可以根据从客户端接收的数据进行处理,然后返回结果)charsendBuf[100];
sprintf(sendBuf,"SendBuf %s is here.",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
//接收(可以持续接收客户端发送的数据)
while(1)
{
charreceiveBuf[100];
recv(sockConn,receiveBuf,100,0);
printf("%s\n",receiveBuf);
}
2.1.8 关闭连接SOCKET,重新等待连接请求
//关闭closesocket(sockConn);
2.1.9 关闭监听SOCKET;
//非无限循环的情况下,应该关闭SOCKET,释放DLLclosesocket(sockSrv);
2.1.10 释放Windows Socket DLL
WSACleanup();2.2 TCP客户端编程
2.2.1 加载Windows Socket DLL
WORD wVersionRequest;WSAData wsaData;
wVersionRequset=MAKEWORD(1,1);
int err=WSAStartup(wVersionRequest,&wsaData);
if(err!=0)
{
return;
}
if(LOBYTE(wVersionRequest)!=1||HIBYTE(wVersionRequest)!=1)
{
WSACleanup();
return;
}
2.2.2 创建SOCKET
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);2.2.3 连接服务器SOCKET
SOCKADDR_IN addrSrv;addrSrv.sin_family=AF_INET;
addSrv.sin_port=htons(6000);
addSrv.sin_addr.S_un.S_addr=inet_addr(“192.186.1.161”);
connect(sockClient,(SOCKADDR*)(&addrSrv ),sizeof(addrSrv));
2.2.4 收发数据
char* sendBuf=”send buf.”;send(sockClient,sendBuf,strlen(sendBuf)+1,0);
char recvBuf=[100];
recv(sockClient,recvBuf,100,0);
2.2.5 关闭SOCKET
closesocket(sockClient);2.2.6 释放Windows Socket DLL
WSACleanup();3 UDP编程
3.1 UPD服务器端编程
3.1.1 加载Windows Socket DLL
WORD wVersionRequest;WSAData wsaData;
int err;
wVersionRequest=MAKEWORD(1,1);
err=WSAStartup(wVersionRequest,&wsaData);
if(err!=0)
{
return;
}
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
{
WSACleanup();
return;
}
3.1.2 创建SOCKET
SOCKET sockSrv= socket(AF_INET,SOCK_DGRAM,0);if(sockSrv ==INVALID_SOCKET)
{
return;
}
3.1.3 绑定SOCKET
SOCKADDR_IN addrSrv;addrSrv.sin_family=AF_INET;
addrSrv.sin_addr.S_un.S_addr=htonl(ADDR_ANY);
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)(&addrSrv),sizeof(SOCKADDR));
3.1.4 收发数据
char recvBuf[100];int len=sizeof(SOCKADDR);
SOCKADDR_IN addrClient;
recvfrom(sockSrv,recvBuf,100,0,(SOCKETADDR*)(*addrClient),&len);
char* sendBuf=”this is from server.”;
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKETADDR*)(&addrClient),len);
3.1.5 关闭SOCKET
closesocket(sockSrv);3.1.6 释放Windows Socket DLL
WSACleanup();3.2 UPD客户端编程
3.2.1 加载Windows Socket DLL
WORD wVersionRequest;WSAData wsaData;
int err;
wVersionRequest=MAKEWORD(1,1);
err=WSAStartup(wVersionRequest,&wsaData);
if(err!=0)
{
return;
}
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
{
WSACleanup();
return;
}
3.2.2 创建SOCKET
SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0);if(sockClient ==INVALID_SOCKET)
{
return;
}
3.2.3 收发数据
SOCKADDR_IN addrSrv;addrSrv.sin_family=AF_INET;
addSrv.sin_port=htons(6000);
addSrv.sin_addr.S_un.S_addr=inet_addr(“192.168.1.161”);
int len=sizeof(SOCKADDR);
char* sendBuf=”this is from client.”;
sendto(sockClient,sendBuf,sizeof(sendBuf)+1,0,(SOCKADDR*)(&addrSrv),len);
char recvBuf[100];
recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)(&addrSrv),&len);
3.2.4 关闭SOCKET
closesocket(sockClient);3.2.5 释放Windows Socket DLL
WSACleanup();4 Qt网络编程
Qt网络编程使用的是Qt的网络模块(QtNetworkModule),在该模块中,各种网络编程协议都进行了相应的封装,更加方便使用.FTP:QFtp;
Http:QNetworkAccessManager,QtNetworkReply;(QHttp类的替代);
本机信息:QHostInfo;
TCP:QTcpServer,QTcpSocket;
UDP:QUdpSocket;
代理:QNetworkProxy;
加密:QSslSocket;
使用时要添加Network模块,并包含QtNetwork模块;
4.1 HTTP
4.1.1 HTTP网络编程相关类:
QNetworkAccessManager:控制HTTP连接的关键类;一般一个程序中使用一个就可满足;用于发出请求,获得响应;QNetworkReply:HttpReply的具体类实现,作为请求的响应,由QNetworkAccessManager返回;以串行化形式返回获得的数据;如果获得数据,就会发出readyRead()信号和downloadProgress()信号(可以不准);如果数据接收完成,就会发出finished()信号;
QNetworkRequest:HttpRequest的具体类实现;作为请求,由QNetworkAccessManager发出;
4.1.2 HTTP步骤:
4.1.2.1 创建QNetworkAccessManager类对象:
QNetworkAccessMangager*m_pHttpManager=new QNetworkAccessManager;4.1.2.2 创建QNetworkRequest对象:
QUrl url(“urlhost”);QNetworkReqest request(url);
4.1.2.3 创建QNetworkReply类对象:
QNetworkReply*m_pRelpy=m_pHttpManger->get(request);4.1.2.4 连接读数据信号与槽函数:
connect(m_pReply,SIGNAL(readyRead()),this,SLOT(readReadyHttpReply ()));4.1.2.5 连接数据读取完成信号与槽函数:
connect(m_pReply,SIGNAL(finished()),this,SLOT(finishHttpReply ()));4.2 TCP
4.3 FTP
4.3.1 FTP类:QFtp
4.4 UPD服务器端编程
4.4.1 加载Windows Socket DLL
相关文章推荐
- java-模拟tomcat服务器
- Linux socket 初步
- java socket 注意的地方
- java socket 注意的地方
- C#基于UDP实现的P2P语音聊天工具
- C#基于socket模拟http请求的方法
- Lua下基本的网络编程示例
- 简单的Ruby中的Socket编程教程
- Socket不能选择本地IP连接问题如何解决
- C#之Socket操作类实例解析
- 使用C#来编写一个异步的Socket服务器
- C#基于UDP进行异步通信的方法
- C#使用Socket快速判断数据库连接是否正常的方法
- TCP版backshell的VBS脚本代码
- 科学知识:理解socket
- 距离详解Linux下的UDP方式通讯
- linux网络编程用到的网络函数详解用和使用示例
- Android聊天工具基于socket实现
- php与flash as3 socket通信传送文件实现代码
- 解决time_wait强制关闭socket