做微信商城网站哪家好,wordpress 固定连接 301,响应式网站用什么开发的,品牌茶业都在哪些网站做宣传TCP和UDP属于传输层协议。其中TCP提供IP环境下的数据可靠传输#xff0c;它事先为要发送的数据开辟好连接通道#xff08;三次握手#xff09;#xff0c;然后再进行数据发送#xff1b;而UDP则不为IP提供可靠性#xff0c;一般用于实时的视频流传输#xff0c;像rtp、r…TCP和UDP属于传输层协议。其中TCP提供IP环境下的数据可靠传输它事先为要发送的数据开辟好连接通道三次握手然后再进行数据发送而UDP则不为IP提供可靠性一般用于实时的视频流传输像rtp、rtsp就是建立在udp的基础上的。 首先谈谈tcp socket tcp简单的三次握手过程如图 SYN(Synchronize Sequence Numbers)同步标志 ACK(Acknowledgement Number) 确认标志 图中可以看出三次握手的过程是在c的connect()和s的bind()、listen()、accept()函数中完成的这样开辟了相对可靠的连接通道来传输数据。
UDP的socket编程过程如下图所示 下面翠花上代码啦
服务端 [cpp] view plaincopyprint? #include stdio.h #include Winsock2.h //windows socket的头文件 #pragma comment( lib, ws2_32.lib )// 链接Winsock2.h的静态库文件 void main() { //初始化winsocket WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested MAKEWORD( 1, 1 );//第一个参数为低位字节第二个参数为高位字节 err WSAStartup( wVersionRequested, wsaData );//对winsock DLL动态链接库文件进行初始化协商Winsock的版本支持并分配必要的资源。 if ( err ! 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) ! 1 ||HIBYTE( wsaData.wVersion ) ! 1 )//LOBYTE取得16进制数最低位HIBYTE取得16进制数最高最左边那个字节的内容 { WSACleanup( ); return; } SOCKET sockSrvsocket(AF_INET,SOCK_STREAM,0);//创建socket。AF_INET表示在Internet中通信SOCK_STREAM表示socket是流套接字对应tcp0指定网络协议为TCP/IP SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addrhtonl(INADDR_ANY); //htonl用来将主机字节顺序转换为网络字节顺序(to network long) //INADDR_ANY就是指定地址为0.0.0.0的地址, //表示不确定地址,或“任意地址”。” addrSrv.sin_familyAF_INET; addrSrv.sin_porthtons(4000);//htons用来将主机字节顺序转换为网络字节顺序(to network short) bind(sockSrv,(SOCKADDR*)addrSrv,sizeof(SOCKADDR));//将本地地址绑定到所创建的socket上以使在网络上标识该socket listen(sockSrv,5);//socket监听准备接受连接请求。 SOCKADDR_IN addrClient; int lensizeof(SOCKADDR); while(1) { SOCKET sockConnaccept(sockSrv,(SOCKADDR*)addrClient,len);//为一个连接请求提供服务。addrClient包含了发出连接请求的客户机IP地址信息返回的新socket描述服务器与该客户机的连接 char sendBuf[50]; sprintf(sendBuf,Welcome %s to here!,inet_ntoa(addrClient.sin_addr));//inet_ntoa网络地址转换转点分十进制的字符串指针 send(sockConn,sendBuf,strlen(sendBuf)1,0); char recvBuf[50]; recv(sockConn,recvBuf,50,0); printf(%s\n,recvBuf); closesocket(sockConn); Sleep(2000);//2000毫秒 } WSACleanup(); } #include stdio.h
#include Winsock2.h //windows socket的头文件
#pragma comment( lib, ws2_32.lib )// 链接Winsock2.h的静态库文件
void main()
{
//初始化winsocket
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested MAKEWORD( 1, 1 );//第一个参数为低位字节第二个参数为高位字节
err WSAStartup( wVersionRequested, wsaData );//对winsock DLL动态链接库文件进行初始化协商Winsock的版本支持并分配必要的资源。
if ( err ! 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) ! 1 ||HIBYTE( wsaData.wVersion ) ! 1 )//LOBYTE取得16进制数最低位HIBYTE取得16进制数最高最左边那个字节的内容
{
WSACleanup( );
return;
}
SOCKET sockSrvsocket(AF_INET,SOCK_STREAM,0);//创建socket。AF_INET表示在Internet中通信SOCK_STREAM表示socket是流套接字对应tcp0指定网络协议为TCP/IP
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addrhtonl(INADDR_ANY); //htonl用来将主机字节顺序转换为网络字节顺序(to network long)
//INADDR_ANY就是指定地址为0.0.0.0的地址,
//表示不确定地址,或“任意地址”。”
addrSrv.sin_familyAF_INET;
addrSrv.sin_porthtons(4000);//htons用来将主机字节顺序转换为网络字节顺序(to network short)
bind(sockSrv,(SOCKADDR*)addrSrv,sizeof(SOCKADDR));//将本地地址绑定到所创建的socket上以使在网络上标识该socket
listen(sockSrv,5);//socket监听准备接受连接请求。
SOCKADDR_IN addrClient;
int lensizeof(SOCKADDR);
while(1)
{
SOCKET sockConnaccept(sockSrv,(SOCKADDR*)addrClient,len);//为一个连接请求提供服务。addrClient包含了发出连接请求的客户机IP地址信息返回的新socket描述服务器与该客户机的连接
char sendBuf[50];
sprintf(sendBuf,Welcome %s to here!,inet_ntoa(addrClient.sin_addr));//inet_ntoa网络地址转换转点分十进制的字符串指针
send(sockConn,sendBuf,strlen(sendBuf)1,0);
char recvBuf[50];
recv(sockConn,recvBuf,50,0);
printf(%s\n,recvBuf);
closesocket(sockConn);
Sleep(2000);//2000毫秒
}
WSACleanup();
}
客户端 [cpp] view plaincopyprint? #include stdio.h #include Winsock2.h #pragma comment( lib, ws2_32.lib ) void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested MAKEWORD( 1, 1 );//第一个参数为低位字节第二个参数为高位字节 err WSAStartup( wVersionRequested, wsaData );//对winsock DLL动态链接库文件进行初始化协商Winsock的版本支持并分配必要的资源。 if ( err ! 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) ! 1 ||HIBYTE( wsaData.wVersion ) ! 1 )//LOBYTE取得16进制数最低位HIBYTE取得16进制数最高最左边那个字节的内容 { WSACleanup( ); return; } for(int index0;;index) { SOCKET sockClientsocket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addrClt;//需要包含服务端IP信息 addrClt.sin_addr.S_un.S_addrinet_addr(192.168.0.30);// inet_addr将IP地址从点数格式转换成网络字节格式整型。 addrClt.sin_familyAF_INET; addrClt.sin_porthtons(4000); connect(sockClient,(SOCKADDR*)addrClt,sizeof(SOCKADDR));//客户机向服务器发出连接请求 char recvBuf[50]; recv(sockClient,recvBuf,50,0); printf(my reply is : %s\n,recvBuf); char sendBuf[50]; sprintf(sendBuf,%3d,,index); strcat(sendBuf,server node of: yaopeng); send(sockClient,sendBuf,strlen(sendBuf)1,0); closesocket(sockClient); Sleep(2000); } WSACleanup(); } #include stdio.h
#include Winsock2.h
#pragma comment( lib, ws2_32.lib )
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested MAKEWORD( 1, 1 );//第一个参数为低位字节第二个参数为高位字节
err WSAStartup( wVersionRequested, wsaData );//对winsock DLL动态链接库文件进行初始化协商Winsock的版本支持并分配必要的资源。
if ( err ! 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) ! 1 ||HIBYTE( wsaData.wVersion ) ! 1 )//LOBYTE取得16进制数最低位HIBYTE取得16进制数最高最左边那个字节的内容
{
WSACleanup( );
return;
}
for(int index0;;index)
{
SOCKET sockClientsocket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrClt;//需要包含服务端IP信息
addrClt.sin_addr.S_un.S_addrinet_addr(192.168.0.30);// inet_addr将IP地址从点数格式转换成网络字节格式整型。
addrClt.sin_familyAF_INET;
addrClt.sin_porthtons(4000);
connect(sockClient,(SOCKADDR*)addrClt,sizeof(SOCKADDR));//客户机向服务器发出连接请求
char recvBuf[50];
recv(sockClient,recvBuf,50,0);
printf(my reply is : %s\n,recvBuf);
char sendBuf[50];
sprintf(sendBuf,%3d,,index);
strcat(sendBuf,server node of: yaopeng);
send(sockClient,sendBuf,strlen(sendBuf)1,0);
closesocket(sockClient);
Sleep(2000);
}
WSACleanup();
}
对于tcp socket有几点需要注意:
一、TCP的TIME_WAIT状态(等待客户端的相应)
注* TIME_WAIT 状态最大保持时间是2 * MSL也就是1-4分钟MSL是最大分段生存期指明TCP报文在Internet上最长生存时间 当服务器端socket绑定本地地址并占用了端口此时如果匆忙结束或者连接的服务器异常退出这个时候被占用的端口不能马上释放需要TIME_WAIT。即便调用closesocket()一般也不会立即关闭socket仍可继续重用该socket。所以重新启动服务器时可能会出现问题。例如MFC中在子窗口中实现socket通信那么关闭子窗口再打开就会出问题了。 解决方法是在bind()之前添加setsockopt()函数解除端口绑定。
介绍setsockopt()之前我们再来回顾一下三次握手协议的具体流程
第一次握手建立连接时客户端发送syn包(synj)到服务器并进入SYN_SEND状态等待服务器确认 第二次握手服务器收到syn包必须确认客户的SYNackj1同时自己也发送一个SYN包synk即SYNACK包此时服务器进入SYN_RECV状态 第三次握手客户端收到服务器的SYNACK包向服务器发送确认包ACK(ackk1)此包发送完毕客户端和服务器进入ESTABLISHED状态完成三次握手。
完成三次握手客户端与服务器开始传送数据。
setsockopt()使用方法如下 1. 如果在已经处于 ESTABLISHED状态下的socket(一般由端口号和标志符区分调用closesocket一般不会立即关闭而经历TIME_WAIT的过程后想继续重用该socket BOOL bReuseaddrTRUE; setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)bReuseaddr,sizeof(BOOL)); 2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭不经历TIME_WAIT的过程 BOOL bDontLinger FALSE; setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)bDontLinger,sizeof(BOOL)); 更多setsockopt()函数用例可参考百度百科http://baike.baidu.com/view/569217.htm 二、对于大型文件一般需要将其剁碎了一部分一部分的传。TCP不能保证接收方顺序的收到包对于需要实时显示的文件可以在发送方发出包后设置来自接收方的响应即对方收到前一个包后再发送下一个包。
目前就这么多各位看官有其他的注意事项拜托请留言补充小弟感激啊。 下面简单说下UDP socket UDP不能保证双方的可靠连接容易出现丢包现象。 UDP的socket编程过程如下图所示 上代码了哈哈。
服务端 [cpp] view plaincopyprint? #include stdio.h #include Winsock2.h #pragma comment( lib, ws2_32.lib ) void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested MAKEWORD( 1, 1 ); err WSAStartup( wVersionRequested, wsaData ); if ( err ! 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) ! 1 || HIBYTE( wsaData.wVersion ) ! 1 ) { WSACleanup( ); return; } SOCKET sockSrvsocket(AF_INET,SOCK_DGRAM,0); int lensizeof(SOCKADDR); SOCKADDR_IN from; SOCKADDR_IN local; local.sin_addr.S_un.S_addrhtonl(INADDR_ANY); local.sin_familyAF_INET; local.sin_porthtons(27015); int a bind(sockSrv,(SOCKADDR*)local,len); while(1) { char recvBuf[50]; recvfrom(sockSrv,recvBuf,50,0,(SOCKADDR*)from,len);//from收到客户端的IP信息 printf(%s\n,recvBuf); printf(%s\n,inet_ntoa(local.sin_addr)); char sendBuf[50]; sprintf(sendBuf,Welcome %s to here!,inet_ntoa(from.sin_addr)); sendto(sockSrv,sendBuf,strlen(sendBuf)1,0,(SOCKADDR*)from,len); Sleep(2000); } closesocket(sockSrv); WSACleanup(); } #include stdio.h
#include Winsock2.h
#pragma comment( lib, ws2_32.lib )
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested MAKEWORD( 1, 1 );
err WSAStartup( wVersionRequested, wsaData );
if ( err ! 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) ! 1 ||
HIBYTE( wsaData.wVersion ) ! 1 ) {
WSACleanup( );
return;
}
SOCKET sockSrvsocket(AF_INET,SOCK_DGRAM,0);
int lensizeof(SOCKADDR);
SOCKADDR_IN from;
SOCKADDR_IN local;
local.sin_addr.S_un.S_addrhtonl(INADDR_ANY);
local.sin_familyAF_INET;
local.sin_porthtons(27015);
int a bind(sockSrv,(SOCKADDR*)local,len);
while(1)
{
char recvBuf[50];
recvfrom(sockSrv,recvBuf,50,0,(SOCKADDR*)from,len);//from收到客户端的IP信息
printf(%s\n,recvBuf);
printf(%s\n,inet_ntoa(local.sin_addr));
char sendBuf[50];
sprintf(sendBuf,Welcome %s to here!,inet_ntoa(from.sin_addr));
sendto(sockSrv,sendBuf,strlen(sendBuf)1,0,(SOCKADDR*)from,len);
Sleep(2000);
}
closesocket(sockSrv);
WSACleanup();
} 客户端 [cpp] view plaincopyprint? #include stdio.h #include Winsock2.h #pragma comment( lib, ws2_32.lib ) void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested MAKEWORD( 1, 1 ); err WSAStartup( wVersionRequested, wsaData ); if ( err ! 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) ! 1 || HIBYTE( wsaData.wVersion ) ! 1 ) { WSACleanup( ); return; } for(int index0;;index) { SOCKET sockClientsocket(AF_INET,SOCK_DGRAM,0); int len sizeof(SOCKADDR); SOCKADDR_IN local; local.sin_addr.S_un.S_addrinet_addr(192.168.0.30); local.sin_familyAF_INET; local.sin_porthtons(27015); char sendBuf[30]; sprintf(sendBuf,%3d,,index); strcat(sendBuf,server node of: yaopeng); sendto(sockClient,sendBuf,strlen(sendBuf)1,0,(SOCKADDR*)local,len); char recvBuf[50]; recvfrom(sockClient,recvBuf,50,0,(SOCKADDR*)local,len); printf(my reply is : %s\n,recvBuf); printf(%s\n,inet_ntoa(local.sin_addr)); closesocket(sockClient); Sleep(2000); WSACleanup(); } }