}
}
closesocket(sClient);
WSACleanup();
}
本机上客户端与服务器端通信结果如图:
在两台服务器上分别运行服务器端和客户端,结果如图:
UDP通信
原理如图:
代码:
服务器端:
#include"stdafx.h"
#include
#include
#include
#definebuffer_length512
#pragmacomment(lib,"WS2_32.lib")
voidmain()
{
WSADATAwsadata;
SOCKETsSocket;
intilen;
intirecv;
charrecv_buf[buffer_length];
charsend_buf[buffer_length];
//服务器和客户SOCKET地址结构
structsockaddr_inseradd,cliadd;
if(WSAStartup(MAKEWORD(2,2),&wsadata)!
=0)
{
printf("failedtoloadwinsocket\n");
return;
}
sSocket=socket(AF_INET,SOCK_DGRAM,0);
if(sSocket==INVALID_SOCKET)
{
printf("socket()failed:
%d\n",WSAGetLastError());
return;
}
//初始化服务器SOCKET地址结构
seradd.sin_family=AF_INET;
seradd.sin_port=htons(6666);
//seradd.sin_addr.s_addr=htonl(INADDR_ANY);
seradd.sin_addr.s_addr=inet_addr("0.0.0.0");
if(bind(sSocket,(LPSOCKADDR)&seradd,sizeof(seradd))==SOCKET_ERROR)
{
printf("地址绑定时出错:
%d\n",WSAGetLastError());
intrua;
scanf("%d",&rua);
return;
}
ilen=sizeof(cliadd);
//初始化接收缓冲区
memset(recv_buf,0,sizeof(recv_buf));
irecv=recvfrom(sSocket,recv_buf,buffer_length,0,(structsockaddr*)&cliadd,&ilen);
if(irecv==SOCKET_ERROR)
{
printf("接收出错%d\n",WSAGetLastError());
intrua;
scanf("%d",&rua);
return;
}
elseif(irecv==0)
return;
else
{
printf("\n%s--",recv_buf);
printf("ServerreceivedfromClientip:
[%s],port:
[%d]\n",inet_ntoa(cliadd.sin_addr),ntohs(cliadd.sin_port));
}
while
(1)
{
//在此函数中cli为传出参数
irecv=recvfrom(sSocket,recv_buf,buffer_length,0,(structsockaddr*)&cliadd,&ilen);
if(irecv==SOCKET_ERROR)
{
printf("接收出错%d\n",WSAGetLastError());
intrua;
scanf("%d",&rua);
return;
}
elseif(irecv==0)
break;
else
{
printf("\n%s--",recv_buf);
printf("ServerreceivedfromClientip:
[%s],port:
[%d]\n",inet_ntoa(cliadd.sin_addr),ntohs(cliadd.sin_port));
}
scanf("%s",send_buf);
sendto(sSocket,send_buf,sizeof(send_buf),0,(structsockaddr*)&cliadd,sizeof(cliadd));
}
closesocket(sSocket);
WSACleanup();
}
客户端:
#include"stdafx.h"
#include
#include
#definedata_buffer1024
voidmain()
{
WSADATAwsadata;
SOCKETsclient;
//服务器地址、端口号
char*serip="192.168.8.58";
intSeriport=6666;
charch[]="qita";
//服务器SOCKET地址结构长度
intilen;
//发送/接收数据大小
intisend;
intirecv;
//要发送给服务器的数据
charsend_buf[]="hello,Iamaclient.";
charrecv_buf[data_buffer];
//服务器端的SOCKET地址结构
structsockaddr_inseradd,cliadd;
//初始化接收缓冲区
memset(recv_buf,0,sizeof(recv_buf));
//字符数组初始化
memset(ch,0,sizeof(ch));
if(WSAStartup(MAKEWORD(2,2),&wsadata)!
=0)
{
printf("failedtoloadwinsock\n");
return;
}
//服务器SOCKET地址结构初始化
seradd.sin_family=AF_INET;
seradd.sin_port=htons(Seriport);
seradd.sin_addr.s_addr=inet_addr(serip);
cliadd.sin_family=AF_INET;
cliadd.sin_port=htons(7777);
cliadd.sin_addr.s_addr=inet_addr("0.0.0.0");
sclient=socket(AF_INET,SOCK_DGRAM,0);
if(sclient==INVALID_SOCKET)
{
printf("buildsocketfailed!
\n");
return;
}
if(bind(sclient,(LPSOCKADDR)&cliadd,sizeof(cliadd))==SOCKET_ERROR)
{
printf("地址绑定时出错:
%d\n",WSAGetLastError());
return;
}
//无连接不需要进行地址与套接字的绑定,直接发送数据即可
ilen=sizeof(seradd);
isend=sendto(sclient,send_buf,sizeof(send_buf),0,(structsockaddr*)&seradd,ilen);
if(isend!
=0&&isend!
=SOCKET_ERROR)
{
//printf("datahasbeensentsuccessfully!
\n");
printf("客户所发的数据为:
%s,字节数为:
%d\n",send_buf,isend);
}
elsereturn;
while
(1)
{
scanf("%s",ch);
sendto(sclient,ch,sizeof(ch),0,(structsockaddr*)&seradd,sizeof(seradd));
irecv=recvfrom(sclient,recv_buf,data_buffer,0,(structsockaddr*)&seradd,&ilen);
if(irecv==SOCKET_ERROR)
{
printf("接收出错%d\n",WSAGetLastError());
intrua;
scanf("%d",&rua);
return;
}
elseif(irecv==0)
break;
else
{
printf("\n%s--",recv_buf);
printf("ServerreceivedfromClientip:
[%s],port:
[%d]\n",inet_ntoa(seradd.sin_addr),ntohs(seradd.sin_port));
}
}
closesocket(sclient);
WSACleanup();
}
本机上客户端与服务器端通信结果如图:
在两台服务器上分别运行服务器端和客户端,结果如图:
三、实验中出现的问题
实验中,因为对TCP和UDP中的代码不熟悉,编译时也缺少了头文件,导致在编译时一直都没有通过,最后在老师的提醒下知道了错误所在,才能编译通过。
思考题:
问:
127.0.0.1与本机配置的网络ip地址还有localhost,相互有什么区别?
答:
localhost是个域名,不是地址,它可以被配置为任意的IP地址,不过通常情况下都指向127.0.0.1(ipv4)和[:
:
1](ipv6)
整个127.*网段通常被用作loopback网络接口的默认地址,按惯例通常设置为127.0.0.1。
这个地址在其他计算机上不能访问,就算你想访问,访问的也是自己,因为每台带有TCP/IP协议栈的设备基本上都有localhost/127.0.0.1。
本机地址通常指的是绑定在物理或虚拟网络接口上的IP地址,可供其他设备访问到。
四、心得体会
在本次试验之前,我对于socket编程并不了解,通过向同学请教以及从网上查找资料,对于这个问题我有了初步的了解,能够进行简单的应用,实现了本机以及联机的TCP协议以及UDP协议通讯。
这次实验主要是通过改写代码实现两台计算机之间tcp/udp通信,做起来问题不大,但在代码的理解以及使用上有一定的难度,主要都是通过问同学来解决问题。
通过这次实验,明白了计算机是如何进行tcp/udp通信,更加强化了理论知识。
(注:
文档可能无法思考全面,请浏览后下载,供参考。
可复制、编制,期待你的好评与关注)