中易网

windows下socket如何编程

答案:1  悬赏:50  
解决时间 2021-04-09 22:45
越具体越好,回答好的话,追加~~~~~~~~~~~
最佳答案
一个简单的TCP客户端程序流程
1、使用WSAStartup()初始化WinSock库。
2、使用socket()创建一个IPPROTO_TCP SOCKET。
3、使用gethostbyname()/gethostbyaddr()获取主机信息。
4、使用connect()和我们创建的套接字连接服务器。
5、使用send()/recv()发送和接收数据,直到我们的TCP会话结束。
6、使用closesocket()关闭套接字连接。
7、使用WSACleanup()释放WinSock。
初始化WinSock
正如其它每个WinSock程序一样,我们需要初始化WinSock库。这也基本上是一种检查WinSock是否在当前系统可用的方法,对于以前的版本,我们当然希望是这样。
int wsaret=WSAStartup(0x101,&wsaData);
if(wsaret)
return;
创建SOCKET
套接字是一种实体,它担当了客户端和服务器之间的端点。当客户端连接到服务器之后,就会存在两个套接字——客户端一边的套接字和相应的服务器一边的套接字。让我们来称它们为CLIENTSOCK和SERVERSOCK。当客户端在CLIENTSOCK使用send()时,服务器可以在SERVERSOCK使用recv()来接收客户端所发送的数据,反之亦然。对于我们的目的,我们使用一个名为socket()的函数来创建套接字。
SOCKET conn;
conn=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(conn==INVALID_SOCKET)
return;
获取主机信息
显然,我们在连接到主机(服务器)之前,要获取它的信息。我们可以使用两个函数——gethostbyname()和gethostbyaddr()。当我们拥有服务器的DNS名称时,我们可以使用gethostbyname()函数,例如codeproject.com或ftp.myserver.org之类的名称。当我们拥有要连接的服务器的IP地址时,可以使用gethostbyaddr()函数,例如192.168.1.1或202.54.1.100。
显然,我们希望能使我们的最终用户既能使用DNS名称,也能使用IP地址。那么,为了这些工作对他来说透明,我们需要像下面这样玩一个小把戏。我们对入口字符串使用inet_addr(),这个函数会把一个IP地址转换成一个标准的网络地址格式。这样一来,如果它返回失败,我们就可以知道这个字符串不是一个IP地址,如果它成功的话,我们就可以假设它是一个有效的IP地址了。
if(inet_addr(servername)==INADDR_NONE)
{
hp=gethostbyname(servername);
}
else
{
addr=inet_addr(servername);
hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
}
if(hp==NULL)
{
closesocket(conn);
return;
}
连接到服务器
connect()函数用于向目标服务器建立连接。我们向它传递我们先前创建的套接字和一个sockaddr结构。我们使用由gethostbyname()/gethostbyaddr()返回的主机地址为sockaddr成员赋值,并输入一个要连接的有效端口。
server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);
server.sin_family=AF_INET;
server.sin_port=htons(80);
if(connect(conn,(struct sockaddr*)&server,sizeof(server)))
{
closesocket(conn);
return;
}
会话
当套接字连接建立后,客户端和服务器就可以通过send()和recv()来发送/接收数据了。这通常称为TCP会话。对于我们的特定情况,我们需要进行HTTP会话。和那些复杂的SMTP或POP3协议相比,它还是比较简单的。HTTP的GET命令用于从HTTP服务器上获取文件。这个文件可以是HTML文件、图像文件、压缩文件、MP3文件等等。这样,这个文件就会被发送了(这是它最简单的形式)。当然,还有一些更复杂的方法来使用这个命令。
GET http-path-to-file\r\n\r\n
在我们的程序中,我们像这样来发送GET命令:
sprintf(buff,"GET %s\r\n\r\n",filepath);
send(conn,buff,strlen(buff),0);
当我们发送了这个命令的时候,我们就应该知道服务器就要开始把我们所请求的文件发送给我们了。就像我们使用send()来发送我们的命令一样,我们可以使用recv()来接收服务器发送给我们的数据。我们循环调用recv(),直到它返回零,这时候我们就会知道服务器已经将数据发送完毕了。并且,对于我们的特定情况,我们可以将这些数据写入文件,就像我们要下载并保存这个文件一样。
while(y=recv(conn,buff,512,0))
{
f.Write(buff,y);
}
关闭连接
现在我们的会话结束了,我们必须关闭连接。在我们的情况下,HTTP连接在文件发送完毕之后就会被服务器关闭了,但是这不要紧,我们仍然需要关闭我们的套接字并释放资源。在更加复杂的会话中,我们通常在调用closesocket()之前调用shutdown()来确定缓冲区已经被刷新,否则可能会有部分数据丢失。
closesocket(conn);
释放WinSock
我们调用WSACleanup()来结束WinSock的使用。
WSACleanup();
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
顺义哪有建设银行
呼之欲出造句
冒险岛V104暗影双刀开高科技135以后的升级路
华山这个地址在什么地方,我要处理点事
我的世界这个游戏怎么玩,才能玩好?
香港新世界,新力讯和沙田机房,哪个好一点
请问办理港澳通行证三个月签一次或者两次,一
合肥具体要修多少条地铁?
阜阳 邮局在哪里有
797游戏被人控制吗
四川的房地产开发商在销售一套房子后需要交哪
想说点对公司发展的诗句帮帮忙
中国电信阳光新城营业厅地址有知道的么?有点
铁人三项运动在国内为什么越来越火了?业余想
涪陵火车站到广东东莞东站需要多少时间?
推荐资讯
芬尼空气能热水器的钻石系列比起实用系列有什
想给蛋糕房起名字,什么名字好呢?
杰控上位机软件和西门子plc通讯不上怎么办?
手指甲空变黑吃什么钙片
八神庵为何是天国神族的王子?
蚀刻后线路出现了很规则的缺口,没有查出是曝
初中阶段学过的杜甫和李白的诗带题目
中国名族管弦乐学会的古筝考级证书含金量怎么
手机怎么root后怎么删除自带软件
魔兽3.3.5版战士毕业装备!
vivo y27为什么玩何来云游戏不能多点触控吗
新成立的股份企业,注册资本100万元,但资金
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?