Socket编程 ——UDP 实验报告
来源:互联网 发布:crossgear 知乎 编辑:程序博客网 时间:2024/06/03 22:55
一 客户端数据反射交互
(1)实验内容
要求:利用数据报套接字实现数据传输
- 客户端创建UDP套接字,向指定的服务端发送数据;
- 服务端接收到新数据,显示是谁发送过来的,并把该数据回传给发送方;
- 服务端使用多线程来实现并发
(2)实现方法
Client
unsigned int port; char recvData[255]; cin >> sendData; sendto(sclient,sendData, 255, 0, (sockaddr *)&sin, len); // 向服务器端发送数据
int ret = recvfrom(sclient, (char *)&port, 4, 0, (sockaddr *)&sin, &len); sin.sin_port=htons(port); ret = recvfrom(sclient, recvData,255, 0, (sockaddr *)&sin, &len); if(ret > 0) cout<<recvData<<endl; //接受改变的端口值 并接受反回的信息
while(1) {cout<<"Input your message:";cin >> sendData; sendto(sclient,sendData, sizeof(sendData), 0, (sockaddr *)&sin, len);int ret = recvfrom(sclient, recvData,255, 0, (sockaddr *)&sin, &len); if(ret > 0) cout<<"From server:"<<recvData<<endl; cin>>s; if (s!=s1)//是否关闭套接字 break; } //做到与服务器交互
server
while (true) { char recvData[255]; char sendData[255]; int ret = recvfrom(serSocket, recvData, 255, 0, (sockaddr *)&remoteAddr, &nAddrLen); NUM++;if (ret > 0) cout<<"Connect a new user ,total Nummber is "<<NUM<<endl;//如果有新的用户加入8080端口则用户数量加一 mystruct.client = remoteAddr;mystruct.userid = NUM;memcpy(mystruct.recvData,recvData,255);hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)&mystruct, 0, NULL);//创建新的线程 在线程里生成新的临时端口与用户进行交互 }
子线程代码DWORD WINAPI ClientThread(LPVOID lpParameter){ SOCKET ChildSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //建立新线程······}
int PORT=1024;while ( PORT <= 65535){ serAddr.sin_family = AF_INET; serAddr.sin_port = htons( PORT); serAddr.sin_addr.S_un.S_addr = INADDR_ANY; if (bind(ChildSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) PORT++; else break; } //寻找并绑定可用的端口
my_struct mystruct = (my_struct) lpParameter;//接收主进程的客户端参数client = mystruct ->client;userid = mystruct->userid;//用户识别号 nAddrLen = mystruct->nAddrLen;sendto(ChildSocket,(const char *)&PORT,4, 0, (sockaddr *)&client, nAddrLen); //将端口号发至客户端进行更改sendto(ChildSocket, mystruct->recvData, 255, 0, (sockaddr *)&client, nAddrLen); //第一次信息反弹至客户端
while(1){ int ret = recvfrom(ChildSocket,mystruct-> recvData, 255, 0, (sockaddr *)& client,& nAddrLen); if (ret > 0) cout<<"FROM user"<<userid<<":"<<mystruct->recvData<<endl; //ntohs(serAddr.sin_port) sendto(ChildSocket, mystruct->recvData, 255, 0, (sockaddr *)& client, nAddrLen);}//后续的信息反弹
(3)实验实现
服务器端
多个客户端同时连接 ,实现用户识别及交叉发送数据
用户1
用户2
二 使用UDP套接字实现文件传输
(1)实验内容
- 客户端向服务端发送文件名
- 客户端向服务端传输文件内容
- 双方关闭套接字
(2)实验方法
Client
unsigned int port=0; char recvData[255]; cout<<"Input your filename:"; cin >> name; sendto(sclient,name, 20, 0, (sockaddr *)&sin, len); // 向服务器端发送文件名
int ret = recvfrom(sclient, (char *)&port, 4, 0, (sockaddr *)&sin, &len); sin.sin_port=htons(port); //接受改变的端口值 并接受反回的信息
fp = fopen(name,"rb"); if(fp==NULL) {cout<<"no suchfile again input:"; } fseek(fp,0L,SEEK_END); file_size = ftell( fp ); fseek(fp,0L,SEEK_SET); sendto(sclient,(const char *)&file_size, 4, 0, (sockaddr *)&sin, len); //文件的建立 长度并发送
while(file_size){if(file_size>=1024){fread(data,1,1024,fp);sendto(sclient, data, 1024, 0, (sockaddr *)&sin, len);file_size -= 1024;}else {fread(data,1,file_size,fp); sendto(sclient, data, file_size, 0, (sockaddr *)&sin, len);file_size = 0;}} // 读取文件并传送
Server
int NUM=0; //计算当前用户的数量typedef struct MyStruct{ sockaddr_in client; int nAddrLen; char recvData[255]; int userid; char name[20];}MyStruct, *my_struct ;//定义结构体 在创线程的时候使用
while (true) { char recvData[255]; char sendData[255]; memset(recvData,0,255); recvfrom(serSocket,recvData, 20, 0, (sockaddr *)& remoteAddr,& nAddrLen); NUM++; cout<<"Connect a new user ,total Nummber is "<<NUM<<endl; //如果有新的用户加入8080端口则用户数量加一 mystruct.userid = NUM; mystruct.client = remoteAddr; memcpy(mystruct.name,recvData,20); hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)&mystruct, 0, NULL); //创建新的线程 在线程里生成新的临时端口与用户进行交互 }
创建新线程
SOCKET ChildSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //新的套接字while ( PORT <= 65535){ serAddr.sin_family = AF_INET; serAddr.sin_port = htons( PORT); serAddr.sin_addr.S_un.S_addr = INADDR_ANY; if (bind(ChildSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) PORT++; else break; } //寻找可用的端口
my_struct mystruct = (my_struct) lpParameter; client = mystruct ->client; userid = mystruct->userid; nAddrLen = mystruct->nAddrLen; sendto(ChildSocket,(const char *)&PORT,4, 0, (sockaddr *)&client, nAddrLen); //将端口号发至客户端进行更改
//新建文件char a[4];unsigned int len=0;recvfrom(ChildSocket,(char *)&len, 4, 0, (sockaddr *)& client,& nAddrLen); FILE *dest_fp; dest_fp = fopen(mystruct->name, "ab");while(1){while(len){ if(len>=1024) {recvfrom(ChildSocket,data, 1024, 0, (sockaddr *)& client,& nAddrLen) ;fwrite(data,1, 1024, dest_fp);fflush(dest_fp);len = len - 1024;} else {recvfrom(ChildSocket,data, len, 0, (sockaddr *)& client,& nAddrLen) ;fwrite(data,1,len,dest_fp);fflush(dest_fp);len = 0;}} fclose(dest_fp);}//文件建立与写入
(3)实验实现
服务器每次用户连接创建新的线程
用户一
用户二
文件夹
0 0
- Socket编程 ——UDP 实验报告
- socket编程实验-UDP文件传输
- Socket编程——UDP编程
- socket编程——TCP/UDP数据传输
- java socket编程——UDP通信
- socket编程——UDP协议
- socket编程——TCP/UDP数据传输
- socket编程——TCP/UDP数据传输 .
- socket编程——TCP/UDP数据传输
- socket编程——TCP/UDP数据传输
- socket编程——TCP/UDP数据传输
- 网络编程——UDP Socket
- linux socket编程示例——UDP
- 通信网络实验——UDP 的socket实现
- [gcc编程] socket编程——TCP/UDP数据传输
- Socket套接字编程(二)——UDP编程
- [gcc编程] socket编程——TCP/UDP数据传输
- 【java编程】tcp/udp——Socket网络编程部分
- 五、账户权限修改
- 反射使用全解析
- 使用IDEA和Mybatis实现CRUD(一)
- nodejs 通过ffmpeg,实现微信jsapi上传mp3录音
- git
- Socket编程 ——UDP 实验报告
- Dubbo源码分析——扩展点机制
- linux连接mysql命令
- PAT--1091. Acute Stroke (30)(三维bfs)
- 13. Error analysis: Look at dev set examples to evaluate ideas 错误分析:查看开发集样本来评估idea(《MACHINE
- 知识库--lifecycle interface (46)
- TCP/IP协议三次握手,四次挥手那些事
- [jQuery知识]jQuery之知识十一-Ajax初级
- 京东右边固定导航