#pragma comment(lib, "ws2_32.lib")
#include <winsock.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////
//发送帧
//////////////////////////////////////////////////////////////////////////
void SendFrame(int * frameNumCurrent,int winSizeCurrent,SOCKET * socketConn)
{
char sendBuffer[128]; //发送数据
if (_snprintf(sendBuffer,sizeof(sendBuffer)-1,"%d",*frameNumCurrent) < 0)
{
printf("写数据出错!\n");
return;
}
else
{
sendBuffer[sizeof(sendBuffer)-1] = '\0';
}
//发送数据 第几帧
if(send(*socketConn,sendBuffer,sizeof(sendBuffer),0) == SOCKET_ERROR)
{
printf("发送数据失败!\n");
return;
}
else
{
printf("现在在传送帧%s\n",sendBuffer);
}
}
//////////////////////////////////////////////////////////////////////////
//接收ACK
//////////////////////////////////////////////////////////////////////////
void ReceiveACK(int * frameNumCurrent,SOCKET * socketConn)
{
char recvBuffer[128];//接收数据
int length = sizeof(struct sockaddr);
int frameNum = 0;//接收到的ACK号
//接收ACK,判断是否有超时或者是否错误ACK
if(recv(*socketConn,recvBuffer,sizeof(recvBuffer),0) == SOCKET_ERROR)//出现超时
{
printf("接收数据超时!需要重新传送帧%d\n\n",*frameNumCurrent);
return;
}
else
{
frameNum = atoi(recvBuffer);
//正确ACK
if (frameNum == *frameNumCurrent)
{
//正确ACK 准备传送下一帧
*frameNumCurrent ^= 1;
printf("接收到正确的ACK,已经成功传送帧%d,将要传送帧%d\n\n",(*frameNumCurrent)^1,*frameNumCurrent);
}
//错误ACK
else if (frameNum == ((*frameNumCurrent) ^ 1))
{
//得到错误ACK 不进行操作,主函数中进行重传操作
printf("接收到错误ACK,帧%d传送错误,需要重新传送帧%d\n\n",*frameNumCurrent,*frameNumCurrent);
}
}
}
//////////////////////////////////////////////////////////////////////////
//初始化发送端监听socket
//////////////////////////////////////////////////////////////////////////
BOOL InitSocketSender(SOCKET * socketSender)
{
SOCKADDR_IN addrSender;
WORD wVersionRequested;
WSADATA wsaData;
//版本
wVersionRequested = MAKEWORD(1,1);
//启动
if (WSAStartup( wVersionRequested, &wsaData) != 0)
{
printf("启动不成功!\n");
return FALSE;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
printf("版本错误!\n");
WSACleanup();
return FALSE;
}
//创建socket
*socketSender = socket(AF_INET,SOCK_STREAM,0);
if(*socketSender == INVALID_SOCKET)
{
printf("创建套接字失败!\n");
return FALSE;
}
//创建地址信息
addrSender.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//所有地址
addrSender.sin_family=AF_INET;
addrSender.sin_port=htons(8000);//端口号
//绑定端口
if(bind(*socketSender,(SOCKADDR*)&addrSender,sizeof(struct sockaddr)) == SOCKET_ERROR)
{
printf("绑定失败!\n");
return FALSE;
}
//监听
if (listen(*socketSender,SOMAXCONN) == SOCKET_ERROR)
{
printf("监听失败!\n");
return FALSE;
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//线程函数 用于处理一个客户端请求
//////////////////////////////////////////////////////////////////////////
DWORD WINAPI ConnectClient(LPVOID socketConn)
{
int count = 0;//循环次数计数器
int winSizeCurrent = 0;//当前发送窗口大小
int frameNumCurrent = 0;//当前发送的帧号
printf("初始状态发送窗口是:%d,准备向接收端发送数据\n\n",winSizeCurrent);
++winSizeCurrent;
while(count < 20)
{
SendFrame(&frameNumCurrent,winSizeCurrent,(SOCKET*)socketConn);
ReceiveACK(&frameNumCurrent,(SOCKET*)socketConn);
++count;
}
printf("模拟结束!\n");
//关闭Socket
closesocket(*((SOCKET*)socketConn));
free(socketConn);
return 0;
}
void main()
{
HANDLE hThread;//线程句柄
DWORD threadId;
SOCKET socketSender;//监听socket
SOCKADDR_IN addrReceiver;//服务器地址
int length = sizeof(struct sockaddr);
int timeOut = 3000;//超时3秒
//初始化发送端监听socket
if (!InitSocketSender(&socketSender))
{
printf("初始化失败,退出!\n");
WSACleanup();
return;
}
printf("等待建立连接\n\n");
//循环等待请求
while (TRUE)
{
SOCKET *socketConn = (SOCKET *)malloc(sizeof(SOCKET));
*socketConn = accept(socketSender,(struct sockaddr*)&addrReceiver,&length);
printf("连接建立成功!接收端的地址是:%s\n\n",inet_ntoa(addrReceiver.sin_addr));
if (setsockopt(*socketConn,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeOut,sizeof(timeOut)) == SOCKET_ERROR)
{
printf("设置接收时限错误!");
closesocket(*socketConn);
continue;
}
//开辟线程处理一个客户端请求
hThread = CreateThread(NULL,0,ConnectClient,(LPVOID)socketConn,0,&threadId);
}
//清理操作
closesocket(socketSender);
WSACleanup();
system("pause");
}
使用socket编程模拟滑动窗口协议
4星 · 超过85%的资源 需积分: 50 81 浏览量
2010-04-12
22:47:59
上传
评论 15
收藏 4KB RAR 举报
xuyilai
- 粉丝: 2
- 资源: 2
- 1
- 2
- 3
- 4
前往页