Socket编程 ——UDP 实验报告

2023-05-16

一 客户端数据反射交互

(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)实验实现

服务器每次用户连接创建新的线程
这里写图片描述

用户一
这里写图片描述
用户二
这里写图片描述

文件夹
这里写图片描述

这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Socket编程 ——UDP 实验报告 的相关文章

  • QT中图表类QChart系列之(1)-基本用法,画折线图、各个类之间的关系

    参考 xff1a https www cnblogs com yunhaisoft p 5180127 html 首先要注意3点 xff1a xff08 1 xff09 在 pro文件中添加 xff1a QT 43 61 charts xf
  • STM32使用FIFO实现USART串口发送中断

    fifo就不要造轮子了 xff0c 用现成的就行了 linux内核中有目前人类写出的基于c语言的最强FIFO xff0c 请自行搜索学习 巧夺天工的kfifo xff0c kfifo精妙无比 xff0c 实在是高 xff0c 其中用到的环回
  • c++的json读取操作

    使用的开源库是nlohmann json 后续操作也都是基于该开源库操作 本地json文件如下 xff1a 34 model config 34 34 model type 34 34 paddlex 34 34 model cfg fil
  • 三维重建了解

    一 三维重建方法 1 1 传统方法 RGBD D来源结构光或者TOF xff1a 缺点 xff0c 重建范围受限 xff0c 一般不能重建大模型 xff1b 比如 xff0c kinectFusion xff0c DynamicFusion
  • docker容器常用命令

    一 常用命令 显示本地镜像 xff1a docker images 显示已经启动的容器 xff1a docker ps a 从docker hub拉取镜像 reed98 airsim v0是镜像名 xff1a docker pull ree
  • ARM学习随笔(12)定时器查询方式和中断方式

    定时器详细讲解 百度文库 点击打开链接 xff08 一 xff09 查询方式和中断方式的区别在于 xff1a 查询方式不断查询标志位然后进行处理 xff0c 而中断要编写中断服务子程序来处理中断事件 xff08 二 xff09 内部中断是指
  • vgg16网络裁剪并加载模型参数

    主要是测试下模型裁剪后转onnx的问题 删除vgg16网络全连接层 xff0c 加载预训练模型并重新保存模型参数 xff0c 将该参数用于转onnx模型格式 usr bin env python coding utf 8 64 Time 2
  • pth转onnx的三种情况

    usr bin env python coding utf 8 64 Time 2022 8 3 16 19 64 Author weiz 64 ProjectName cbir 64 File pth2onnx py 64 Descrip
  • 以vgg为backbone的简易图像检索系统

    图像检索 xff08 Content based Image Retrieval xff0c 简称CBIR xff09 即以图搜图 xff0c 基于图片语义信息 xff0c 诸如颜色 纹理 布局 CNN based高层语义等特征检索技术 该
  • img2pose: Face Alignment and Detection via 6DoF, Face Pose Estimation代码理解

    import argparse import os import sys import time import numpy as np from PIL import Image ImageOps from torchvision impo
  • 解决普通用户使用sudo找不到命令

    sudo bazel build c opt define MEDIAPIPE DISABLE GPU 61 1 mediapipe examples desktop face mesh face mesh cpu 出现 xff1a sud
  • sfm算法之三角化(三角测量)

    sfm算法流程一般是特征点提取 特征点匹配 计算本质矩阵 基础矩阵 xff0c 最后三角化 但是利用机械臂去观察周围 xff0c 前后帧姿态变化参数是具有的 xff0c 所以不需要通过基础矩阵获取 即利用机械臂的信息直接进行深度估计 已知
  • bazel构建项目案例(第三方库,编译成库,运行案例)

    使用bazel构建项目 xff0c 包含如何引入外部库 xff08 项目中引入了opencv和编译的tensorflow lite库 xff09 xff0c 如何编译成动态库和静态库 xff0c 以及如何调用编译好的库 项目根目录的所有文件
  • 各种小功能集二

    各种小功能集一 十一 C C 43 43 路径解析 头文件 std string UtilsGetPath const char pszFilename std string UtilsGetDirname const char pszFi
  • windows10配置paddleOCR的CPU版本总结

    paddleOCR的CPU版本依赖的库还是比较少的 如下 1 opencv库 本人配置的版本是opencv4 5 0 2 paddle inference 推理库 该库解压后有version txt文件 xff0c 版本信息如下 xff1a
  • 传统图像技术的边缘提取

    usr bin env python coding utf 8 import cv2 import os import numpy as np def laplacian img ksize 61 3 laplacian 61 cv2 La
  • TCP-UDP网络编程调试助手下载

    下载地址 xff1a 可能需要谷歌 xff1a 软件干净 xff0c 挺好用的 xff0c 如果有更好的 xff0c 欢迎留言 xff01 https www waveshare com wiki File TCP UDP Debug 7z
  • Data Matrix码的使用

    一 引言 Data Matrix原名Data code xff0c 由美国国际资料公司 International Data Matrix 简称ID Matrix 于1989年发明 Data Matrix又可分为ECC000 140与ECC
  • 小样本学习(Few-Shot Learning)训练参数意义

    一 常规参数 1 1 epoch 是指所有的训练数据都要跑一遍 假设有6400个样本 xff0c 在训练过程中 xff0c 这6400个样本都跑完了才算一个epoch 一般实验需要训练很多个epoch xff0c 直到LOSS稳定后才停止
  • 不同相机之间图片像素对应关系求解(单应性矩阵求解)

    一 场景 相机1和相机2相对位置不变 xff0c 相机拍摄图片有重叠 xff0c 求他们交叠部分的一一对应关系 数学语言描述为已知相机1图片中P点像素 u1 v1 xff0c 相机1中P点在相机2图片中像素值为 u2 v2 xff0c 它们

随机推荐