PS:下面是我学习整理所得,希望对大家有帮助
通信条件:
1、IP地址
2、相同的协议
3、端口号(相当于IP是总号码,这是分号)
七层参考模型
1、物理层(实质是物理层进行传输)
提供二进制创术,确定在通信信道上如何传输比特流。
2、数据链路层
建立一条传输线路
3、网络层
IP寻址和路由,找出最佳路线
4、传输层
隔开应用层和底层协议(进程通信)
5、会话层
建立、组织和协调相互通信
6、表示层
数据加密、解密和压缩,数据间的转换
7、应用层
为用户的网络应用程序提供网络通信服务。
但是七层太过复杂,一般使用TCP/IP协议
应用层(对应上三层)
传输层(进程)
网络层
网络接口(对应下两层)
TCP/IP协议
TCP:可靠传输,三次握手建立连接,传出去一定接受的到(保证数据无丢失 程序下载安装)
UDP:不可靠传输,不需要建立连接,只管发送(实时性高 视频会议)
socket
套接字:表示通信的端点。就像用电话通信,套接字相当于电话机,IP地址相当于总机号码,而端口号则相当于分机。
基于udp的socket编程(发送和接受是sendto和recvfrom)
接收端
1、创建套接字
2、将套接字绑定到一个本地地址和端口上(blind)
3、等待接受数据(recvform)
4、关闭套接字。
客户端
1、创建套接字
2、向服务器发送数据(sendo)
3、关闭套接字
基于UDP的socket编程(发送和接受是send和recv)
1、err = WSAStartup(wVersionRequested, &wsaData);//加载套接字库
2、SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);//创建套接字
3、bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//绑定套接字端口
4、recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);//等待数据并接受
sprintf_s(tempBuf,"%s say : %s",inet_ntoa(addrClient.sin_addr),recvBuf);//放入buff
printf("%s\n",tempBuf);//输出显示
5、gets(sendBuf);//过的输入数据
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);//发送
下面是代码 UDPSrv
//UdpNetSrv.cpp
#include <Winsock2.h>
#include <stdio.h>
void main()
{
//加载套接字库
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1,1);
err = WSAStartup(wVersionRequested, &wsaData);//错误会返回WSASYSNOTREADY
if(err != 0)
{
return;
}
if(LOBYTE(wsaData.wVersion) != 1 || //低字节为主版本
HIBYTE(wsaData.wVersion) != 1) //高字节为副版本
{
WSACleanup();
return;
}
printf("server is operating!\n\n");
//创建用于监听的套接字
SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);//失败会返回 INVALID_SOCKET
//printf("Failed. Error Code : %d",WSAGetLastError())//显示错误信息
SOCKADDR_IN addrSrv; //定义sockSrv发送和接收数据包的地址
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));//会返回一个SOCKET_ERROR
//将套接字设为监听模式, 准备接收客户请求
SOCKADDR_IN addrClient; //用来接收客户端的地址信息
int len = sizeof(SOCKADDR);
char recvBuf[100]; //收
char sendBuf[100]; //发
char tempBuf[100]; //存储中间信息数据
while(1)
{
//等待并数据
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
if('q' == recvBuf[0])
{
sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);
printf("Chat end!\n");
break;
}
sprintf_s(tempBuf,"%s say : %s",inet_ntoa(addrClient.sin_addr),recvBuf);
printf("%s\n",tempBuf);
//发送数据
printf("Please input data: \n");
gets(sendBuf);
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);
}
closesocket(sockSrv);
WSACleanup();
}
UPDclient 代码
//UdpNetClient.cpp
#include <Winsock2.h>
#include <stdio.h>
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;
}
printf("Client is operating!\n\n");
//创建用于监听的套接字
SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);
sockaddr_in addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//输入你想通信的她(此处是本机内部)
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
int len = sizeof(SOCKADDR);
char recvBuf[100]; //收
char sendBuf[100]; //发
char tempBuf[100]; //存储中间信息数据
while(1)
{
printf("Please input data: \n");
gets(sendBuf);
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrSrv,len);
//等待并数据
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);
if('q' == recvBuf[0])
{
sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrSrv,len);
printf("Chat end!\n");
break;
}
sprintf_s(tempBuf,"%s say : %s",inet_ntoa(addrSrv.sin_addr),recvBuf);
printf("%s\n",tempBuf);
//发送数据
}
closesocket(sockSrv);
WSACleanup();
}