一、实验目的
通过使用Socket API,加深对TCP和UDP Socket 的认识。
二、实验要求
两位同学一组,共同完成服务器与客户端程序编写。
甲同学通过tcp连接到乙同学服务器(ip:*.*.*.*,端口号:8888)。
甲发送自己的学号和姓名到乙服务器,乙服务器返回一个自己的学号和姓名给甲。
然后甲通过UDP提交获取到的学号和姓名给乙,如果乙收到正确的信息,则返回的信息为:恭喜,实验成功!!若收到信息不对,则返回的信息为:错误认证,实验没有成功!
三、实验步骤
1.甲同学通过TCP连接乙同学服务器 ip:*.*.*.* 端口号:8888
2.使用TCP发送自己的学号和姓名到服务器(姓名用汉语拼音)。
3.乙同学TCP服务器返回一个自己的学号和姓名给甲,客户端可以使用如下方法来获取。
/*********************************************
#define _MagicNumberT 0xFFFE3141 //tcp标识
#define _MagicNumberU 0xFFEF3141 // udp标识
#define _ID_Len 32
#define_NAME_Len 256
typedef struct Packet
{
DWORD magicnum;
unsigned char ID[_ID_Len];//学号
unsigned char Name[_NAME_Len];//姓名
}package;
package recvBuffer;
send(TCPSocket,(char*)&sendBuffer,sizeof(_A1_Packet),0);//发送TCP 请求包
recv(TCPSocket,(char*)&recvBuffer,sizeof(_A1_Packet),0);//接收TCP服务器端的回应puts((char*)recvBuffer.PostData);
***************************************************/
4. 甲通过UDP连接服务器乙,将上面接收到的学号和姓名,发送给UDP服务器乙。
使用sendto()发送到服务器
使用recvfrom()等待服务器的返回信息
5. UDP服务器的返回信息存放在PostData[]中。客服端通过如下方法来查看UDP服务器返回的信息:
puts((char*)recvBuffer.PostData);
若两次学号与姓名一样,则返回的信息为:恭喜,实验成功!!
若两次学号与姓名不一样,则返回的信息为:两次字符串不一样,实验没有成功!
实验截图:
首先开启服务器端:
再开启客户端:
服务器端显示:
源代码:
客户端代码:Client.cpp
#include #include #include #include #define _MagicNumberT 0xFFFE3141 // TCP 数据包头部标识符 #define _MagicNumberU 0xFFEF3141 // UDP 数据包头部标识符 #define _SNDID_Len 32 // 学号长度 #define _PostData_Len 256 // 最大数据长度 #pragma comment(lib,\"ws2_32.lib\") #pragma comment(linker, \"/subsystem:console \") typedef struct { DWORD magicnum; char SNSID[_SNDID_Len]; // 学号字段,长度32 char PostData[_PostData_Len]; // 数据字段,长度256 }_A1_Packet; void main() { // Initialize Winsock //初始化 WSADATA wsaData; int errorCode; int iResult=WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult!=0) { printf(\"初始化套接字失败\\n\"); return ; } //建立socket SOCKET TCPSocket; TCPSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// 创建TCP 套接字 //设置Server 端IP 和端口:(TCP/UDP 相同) if (TCPSocket==INVALID_SOCKET) { printf(\"创建套接字失败\\n\"); closesocket(TCPSocket); WSACleanup(); return ; } //绑socket SOCKADDR_IN server; server.sin_family = AF_INET; server.sin_port = htons(8888); server.sin_addr.s_addr = inet_addr(\"127.0.0.1\"); bind(TCPSocket,(struct sockaddr*)&server,sizeof(server)); errorCode=connect(TCPSocket, (struct sockaddr *)&server, sizeof(server)); //用TCP 连接服务器 if (SOCKET_ERROR == errorCode) { printf(\"连接服务器失败\\n\"); closesocket(TCPSocket); WSACleanup(); // return ; } // 构造请求数据包: _A1_Packet pkgBuffer; pkgBuffer.magicnum = _MagicNumberT; // 用TCP 数据包头部标识符填充magicnum // 用学号填充SNSID[],末尾填\\0 char IDlen=strlen(\"20120014\"); //学号长度 strcpy(pkgBuffer.SNSID,\"20120014\"); pkgBuffer.SNSID[IDlen]='\\0'; //用姓名填充PostDate[],末尾填\\0 char NAMElen=strlen(\"Lei Sheng Ping\"); strcpy(pkgBuffer.PostData,\"Lei Sheng Ping\"); pkgBuffer.PostData[NAMElen]='\\0'; errorCode=send(TCPSocket,(char *)&pkgBuffer,sizeof(pkgBuffer),0);// 发送 TCP 请求包 printf(\"第一次向服务器发送的数据:\\n\"); printf(\"学号:%s \\n\ printf(\"姓名:%s \\n\ if (SOCKET_ERROR == errorCode ) { printf(\"向服务器发送数据失败\\n\"); WSACleanup(); // return ; } _A1_Packet reBuffer; errorCode=recv(TCPSocket,(char *)&reBuffer,sizeof(_A1_Packet),0);// 接收服务器端的回应 if (SOCKET_ERROR==errorCode) { printf(\"接受服务器数据失败\\n\"); closesocket(TCPSocket); WSACleanup(); return ; } printf(\"接受到服务器传来的数据:\\n\"); printf(\"学号:%s \\n\ printf(\"姓名:%s \\n\ //puts((char*)reBuffer.PostData); //puts((char*)reBuffer.SNSID); closesocket(TCPSocket); //初始化UDP Socket SOCKET UDPSocket; UDPSocket=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);// 创建UDP套接字 if (UDPSocket==INVALID_SOCKET) { printf(\"创建套接字失败\\n\"); closesocket(UDPSocket); WSACleanup(); return ; } //修改magicnum 为UDP 数据包头部标识。填写学号SNSID[]和提交的数据PostData[]。 reBuffer.magicnum = _MagicNumberU;//用UDP 数据包头部标识符填充magicnum // 使用sendto()发送到服务器 errorCode=sendto(UDPSocket,(char *)&reBuffer,sizeof(reBuffer), 0, (struct sockaddr *)&server,sizeof(server)); //printf(\"发送%d字节数据包,等待服务器回应....\\n\ printf(\"第二次向服务器发送的数据:\\n\"); printf(\"学号:%s\\n\ printf(\"姓名:%s\\n\ int addrlen=sizeof(struct sockaddr_in); char recvBuf[10]; recvfrom(UDPSocket,recvBuf,10,0,(struct sockaddr *)&server,&addrlen); if( strcmp(recvBuf,\"YES\")==0) printf(\"恭喜,实验成功!!\"); else printf(\"两次字符串不一样,实验没有成功!!\"); closesocket(UDPSocket); WSACleanup(); getch(); system(\"pause\"); } 服务器端:Service.cpp #include #include #include #include #define _MagicNumberT 0xFFFE3141 // TCP 数据包头部标识符 #define _MagicNumberU 0xFFEF3141 // UDP 数据包头部标识符 #define _SNDID_Len 32 // 学号长度 #define _PostData_Len 256 // 最大数据长度 #pragma comment(lib,\"ws2_32.lib\") #pragma comment(linker, \"/subsystem:console \") typedef struct { DWORD magicnum; char SNSID[_SNDID_Len]; // 学号字段,长度32 char PostData[_PostData_Len]; // 数据字段,长度256 }_A2_Packet; void main() { // Initialize Winsock //初始化 WSADATA wsaData; int errorCode; int iResult=WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult!=0) { printf(\"初始化套接字失败\\n\"); return ; } //建立socket SOCKET TCPSocket; TCPSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// 创建TCP 套接字 //设置Server 端IP 和端口:(TCP/UDP 相同) if (TCPSocket==INVALID_SOCKET) { printf(\"创建套接字失败\\n\"); closesocket(TCPSocket); WSACleanup(); return ; } //建立流式套接字 sockaddr_in addr; int nSockErr; addr.sin_addr.S_un.S_addr =inet_addr(\"127.0.0.1\"); addr.sin_family = AF_INET; //设定监听端口8888 addr.sin_port=htons(8888); //绑定套接字 if(bind(TCPSocket,(struct sockaddr*)&addr,sizeof(addr)) == SOCKET_ERROR) { nSockErr = WSAGetLastError(); printf(\"绑定监听失败!\\n\"); } // else // { //printf(\"绑定监听成功!\\n\"); //} //将套接字设置成监听状态 if(listen(TCPSocket,5) == SOCKET_ERROR) { nSockErr = WSAGetLastError(); printf(\"设置监听失败!\\n\"); } else { printf(\"设置监听成功,等待连接!\\n\"); } //等待客户的链接请求 int err,f=0; SOCKADDR_IN addrClient; int len=sizeof(SOCKADDR); SOCKET connectSocket = accept(TCPSocket,(SOCKADDR*)&addrClient,&len); if(connectSocket == INVALID_SOCKET) { printf(\"连接错误!\\n\"); nSockErr = WSAGetLastError(); } else { printf(\"客户端连接成功!\\n\"); _A2_Packet buf; buf.magicnum = _MagicNumberT; //接收客户端传输过来的数据 char n = recv(connectSocket,(char*)&buf,sizeof(_A2_Packet),0); //ar m = recv(connectSocket,buf,2048,0); //printf(\"%s\\n\ printf(\"收到客户端发来的数据:\\n\"); puts((char*)buf.SNSID); puts((char*)buf.PostData); } // 构造请求数据包: _A2_Packet pkgBuffer; pkgBuffer.magicnum = _MagicNumberT; // 用TCP 数据包头部标识符填充magicnum // 用学号填充SNSID[],末尾填\\0 char IDlen=strlen(\"20120025\"); //学号长度 strcpy(pkgBuffer.SNSID,\"20120025\"); pkgBuffer.SNSID[IDlen]='\\0'; //用姓名填充PostDate[],末尾填\\0 char NAMElen=strlen(\"Qin Lu Yan\"); strcpy(pkgBuffer.PostData,\"Qin Lu Yan\"); pkgBuffer.PostData[NAMElen]='\\0'; errorCode=send(connectSocket,(char *)&pkgBuffer,sizeof(pkgBuffer),0);// 发送TCP 请求包 if (SOCKET_ERROR == errorCode ) { printf(\"向客户端发送数据失败\\n\"); closesocket(TCPSocket); WSACleanup(); // return ; } printf(\"向客户端发送的数据:\\n\"); printf(\"学号:%s \\n\ printf(\"姓名:%s \\n\ closesocket(TCPSocket); SOCKET UDPSocket; UDPSocket=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);// 创建UDP套接字 if (UDPSocket==INVALID_SOCKET) { printf(\"创建套接字失败\\n\"); return ; } bind(UDPSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR)); SOCKADDR_IN addrclient; _A2_Packet rebuf; int addrlen=sizeof(struct sockaddr_in); recvfrom(UDPSocket,(char *)&rebuf,sizeof(_A2_Packet), 0, *)&addrclient,&addrlen); char sendbuf[10]; sockaddr (struct if((strcmp(pkgBuffer.PostData,rebuf.PostData)==0)&&(strcmp(pkgBuffer.SNSID,rebuf.SNSID)==0)) strcpy(sendbuf,\"YES\"); else strcpy(sendbuf,\"NO\"); sendto(UDPSocket,sendbuf,10,0,(struct *)&addrclient,sizeof(SOCKADDR)); closesocket(UDPSocket); } sockaddr 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- dfix.cn 版权所有 湘ICP备2024080961号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务