基于WinSock的简单TCP网络编程实验报告.docx
- 文档编号:9144990
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:18
- 大小:235.88KB
基于WinSock的简单TCP网络编程实验报告.docx
《基于WinSock的简单TCP网络编程实验报告.docx》由会员分享,可在线阅读,更多相关《基于WinSock的简单TCP网络编程实验报告.docx(18页珍藏版)》请在冰豆网上搜索。
基于WinSock的简单TCP网络编程实验报告
实验报告
实验课程名称:
通信软件基础实验课
学院:
软件工程学院
专业:
软件工程
指导教师:
报告人姓名:
学号:
班级:
学期:
实验
成绩
实验项目名称
基于WinSock的简单TCP网络编程
一、实验目的与要求:
1、学习和掌握Socket编程的面向连接编程模型。
2、学习和掌握基于WinSock的TCP网络编程方法。
二、实验设备及软件:
笔记本电脑、Window7操作系统、MicrosoftVisualStudio2012
三、实验方法(原理、流程图)
流程图:
四、实验过程、步骤及内容
实验代码:
server.h
#defineMAX_CLIENT10//同时服务的client数目上限
#defineMAX_BUF_SIZE65535//缓存区的大小
constu_shortUDPSrvPort=2345;//Server的UDP端口
constcharSTART_CMD[]="START";
constcharGETCURTIME_CMD[]="GETCURTIME";
//传递给TCP线程的结构化参数
structTcpThreadParam
{
SOCKETsocket;
sockaddr_inaddr;
};
DWORDWINAPITcpServeThread(LPVOIDlpParam);//TCP线程的线程函数
DWORDWINAPIUdpServer(LPVOIDlpParam);//UDP服务器线程
server.cpp
#include"stdafx.h"
#include"iostream.h"
#include"stdio.h"
#include"string.h"
#include"time.h"
#include"WinSock2.h"
#include"Windows.h"
#include"server.h"
#pragmacomment(lib,"Ws2_32.lib")
#pragmapack
(1)//结构在存储时按字节对齐
longTcpClientCount=0;
intmain(intargc,char*argv[])
{
////检查命令行参数
//if(argc!
=2)
//{
//cerr<<"Worngformat!
\nCorrectusage:
Server.exe
//return-1;
//}
//初始化winsock2环境
WSADATAwsa;
if(WSAStartup(MAKEWORD(2,2),&wsa)!
=0)
{
cerr<<"\nFailedtoinitializethewinsock2stack\n"
<<"errorcode:
"< return-1; } //创建UDP服务器 DWORDdwThreadId; CreateThread(NULL,0,UdpServer,NULL,0,&dwThreadId); //创建用于侦听的TCPServerSocket SOCKETListenSocket=socket(AF_INET,SOCK_STREAM,0); //获取TCP监听端口号 u_shortListenPort=(u_short)atoi(argv[1]); //获取本机名 charhostname[256]; gethostname(hostname,sizeof(hostname)); //获取本地IP地址 hostent*pHostent=gethostbyname(hostname); //填充本地TCPSocket地址结构 SOCKADDR_INListenAddr; memset(&ListenAddr,0,sizeof(SOCKADDR_IN)); ListenAddr.sin_family=AF_INET; ListenAddr.sin_port=htons(ListenPort); ListenAddr.sin_addr=*(in_addr*)pHostent->h_addr_list[0]; //绑定TCP端口 if(bind(ListenSocket,(sockaddr*)&ListenAddr,sizeof(ListenAddr))==SOCKET_ERROR) { cerr<<"\nFailedtobindtheListenSocket\n" <<"errorcode: "< return-1; } //监听 if((listen(ListenSocket,SOMAXCONN))==SOCKET_ERROR) { cerr<<"\nFailedtolistentheListenSocket\n" <<"errorcode: "< return-1; } cout<<"TCPServerStartedOnTCPPort: "< SOCKETTcpSocket; SOCKADDR_INTcpClientAddr; while(TRUE) { //接受客户端连接请求 intiSockAddrLen=sizeof(sockaddr); if((TcpSocket=accept(ListenSocket,(sockaddr*)&TcpClientAddr,&iSockAddrLen))==SOCKET_ERROR) { cerr<<"\nFailedtoaccepttheclientTCPSocket\n" <<"errorcode: "< return-1; } //TCP线程数达到上限,停止接受新的Client if(TcpClientCount>=MAX_CLIENT) { closesocket(TcpSocket); cout<<"ConnectionfromTCPclient"< "< continue; } cout<<"ConnectionfromTCPclient"< "< TcpThreadParamParam; Param.socket=TcpSocket; Param.addr=TcpClientAddr; //创建TCP服务线程 DWORDdwThreadId; CreateThread(NULL,0,TcpServeThread,&Param,0,&dwThreadId); InterlockedIncrement(&TcpClientCount); cout<<"CurrentNumberofTCPClients: "< } closesocket(ListenSocket); WSACleanup(); return0; } //TCP服务线程 DWORDWINAPITcpServeThread(LPVOIDlpParam) { charServerTCPBuf[MAX_BUF_SIZE]; //获取线程参数 SOCKETTcpSocket=((TcpThreadParam*)lpParam)->socket; SOCKADDR_INTcpClientAddr=((TcpThreadParam*)lpParam)->addr; //输出提示信息 cout<<"Thread: "< "< //发送端口号+"START" sprintf(ServerTCPBuf,"%5d%s",UDPSrvPort,START_CMD); send(TcpSocket,ServerTCPBuf,strlen(ServerTCPBuf),0); cout<<"WaitingforcommandfromClient(s)..."< intTCPBytesReceived; time_tCurSysTime; while(TRUE) { //读取client发来的请求命令: "GETCURTIME" memset(ServerTCPBuf,'\0',sizeof(ServerTCPBuf)); TCPBytesReceived=recv(TcpSocket,ServerTCPBuf,sizeof(ServerTCPBuf),0); //TCPBytesReceived值为0表示client端已正常关闭连接 //TCPBytesRecieved值为SOCKET_ERROR则表示socket的状态不正常,无法继续数据通讯 //两种情况下都表明本线程的任务已结束,需要退出 if(TCPBytesReceived==0||TCPBytesReceived==SOCKET_ERROR) { cout<<"Clientfrom"< "< "< break; } //检查收到的字符串是否为命令: "GETCURTIME" if(strcmp(ServerTCPBuf,GETCURTIME_CMD)! =0) { cout<<"UnknowmcommandfromClient"< continue; } cout<<"RequestforCurrenttimefromclient"< "< //获取系统时间并发送给client time(&CurSysTime); memset(ServerTCPBuf,'\0',sizeof(ServerTCPBuf)); strftime(ServerTCPBuf,sizeof(ServerTCPBuf),"%Y-%m-%d%H: %M: %S",localtime(&CurSysTime)); send(TcpSocket,ServerTCPBuf,strlen(ServerTCPBuf),0); cout<<"ServerCurrentTime: "< } InterlockedDecrement(&TcpClientCount); closesocket(TcpSocket); return0; } //UDP服务器线程 DWORDWINAPIUdpServer(LPVOIDlpParam) { charServerUDPBuf[MAX_BUF_SIZE];//UDPBuffer SOCKADDR_INUDPClientAddr;//存储Client的地址信息 //创建UDPserversocket SOCKETUDPSrvSocket=socket(AF_INET,SOCK_DGRAM,0); //获取本机名 charhostname[256]; gethostname(hostname,sizeof(hostname)); //获取本地IP地址 hostent*pHostent=gethostbyname(hostname); //填充本地UDPSocket地址结构 SOCKADDR_INUDPSrvAddr; memset(&UDPSrvAddr,0,sizeof(SOCKADDR_IN)); UDPSrvAddr.sin_family=AF_INET; UDPSrvAddr.sin_port=htons(UDPSrvPort); UDPSrvAddr.sin_addr=*(in_addr*)pHostent->h_addr_list[0]; //绑定UDP端口 if(bind(UDPSrvSocket,(sockaddr*)&UDPSrvAddr,sizeof(UDPSrvAddr))==SOCKET_ERROR) { cerr<<"bind()failedforUDPSrvSocket\n" <<"errorcode: "< return-1; } cout<<"UDPServerStartedOnUDPPort: "< while(TRUE) { memset(ServerUDPBuf,'\0',sizeof(ServerUDPBuf)); //接收UDP请求 intiSockAddrLen=sizeof(sockaddr); if((recvfrom(UDPSrvSocket,ServerUDPBuf,sizeof(ServerUDPBuf),0,(sockaddr*)&UDPClientAddr,&iSockAddrLen))==SOCKET_ERROR) { cerr<<"recvfrom()failedforUDPSrvSocket\n" <<"errorcode: "< continue; } cout<<"ClientCommand: Echo\n\n"; cout<<"\""< "< //ECHO iSockAddrLen=sizeof(sockaddr); if((sendto(UDPSrvSocket,ServerUDPBuf,strlen(ServerUDPBuf),0,(sockaddr*)&UDPClientAddr,iSockAddrLen))==SOCKET_ERROR) { cerr<<"sendto()failedforUDPSrvSocket\n" <<"errorcode: "< continue; } cout<<"Echo"<<"\""< "< } return0; } client.exe #include"stdafx.h" #include"WinSock2.h" #include"iostream.h" #include"stdio.h" #pragmacomment(lib,"Ws2_32.lib") #defineMAX_BUF_SIZE65535 charClientBuf[MAX_BUF_SIZE]; constcharSTART_CMD[]="START"; constcharGETCURTIME_CMD[]="GETCURTIME"; //输出用户选择界面 voidUserPrompt() { cout<<"InputthecorrespondingNumtoselectwhatyouwanttheprogramtodo"< <<"\t1.Getcurrenttime(TCP)"< <<"\t2.EchoMode(UDP)"< <<"\t3.Exittheprogram"< <<"EnterYourchoice: "; } intmain(intargc,char*argv[]) { unsignedshortServerUDPPort; SOCKETcTCPSocket,cUDPSocket; WSADATAwsadata; SOCKADDR_INTCPServer,UDPServer,RecvFrom; intRecvFromLength=sizeof(RecvFrom); charUserChoice; charportnum[5]; unsignedlongBytesReceived,BytesSent; intRetValue; //检查命令行参数 if(argc! =3) { cout<<"Worngformat! "< Client.exe return1; } u_longServerIP=inet_addr(argv[1]); u_shortServerTCPPort=(u_short)atoi(argv[2]); //初始化winsock库 if((RetValue=WSAStartup(MAKEWORD(2,2),&wsadata))! =0) { printf("WSAStartup()failedwitherror%d\n",RetValue); return2; } //创建TCPSocket if((cTCPSocket=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET) { printf("WSASocket()forcTCPSocketfailedwitherror%d\n",WSAGetLastError()); return3; } //创建UDPSocket if((cUDPSocket=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET) { printf("WSASocket()forcUDPSocketfailedwitherror%d\n",WSAGetLastError()); return4; } TCPServer.sin_family=AF_INET; TCPServer.sin_port=htons(ServerTCPPort); TCPServer.sin_addr.S_un.S_addr=ServerIP; //通过TCPSocket连接server if((RetValue=WSAConnect(cTCPSocket,(sockaddr*)&TCPServer,sizeof(TCPServer),NULL,NULL,NULL,NULL))==SOCKET_ERROR) { printf("WSAConnect()failedforcTCPSocketwitherror%d\n",WSAGetLastError()); printf("Can'tconnecttoserver.\n"); return5; } //与server建立连接后读取Server发送过来的ServerUDP端口和"START" BytesReceived=recv(cTCPSocket,ClientBuf,sizeof(ClientBuf),0); if(BytesReceived==0||BytesReceived==SOCKET
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 WinSock 简单 TCP 网络 编程 实验 报告