《TCP/IP网络编程》--基于TCP实现字符串对话和文件传输

2023-11-16

1--基于TCP实现字符串对话

主要需求:

        服务器端和客户端各传递 1 次字符串,基于 TCP 协议,传递字符串前先以 4 字节整数型方式传递字符串长度,剩余部分为字符串数据;

注:下面的代码基于 Windows 系统实现;

1-1--服务器端

// gcc string_server_win.c -o string_server_win -lwsock32
// string_server_win 9190

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#define BUF_SIZE 1024
#define Len_SIZE 4

void ErrorHandling(char *message){
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[]){
    if (argc != 2) {
        printf("Usage: %s <port>\n", argv[0]);
	    exit(1);
    }

    WSADATA wsaData; // init Socket lib
    if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){ 
        ErrorHandling("WSAStartup() error!");
    }

    int Serv_sock = socket(PF_INET, SOCK_STREAM, 0); // create socket
    if (Serv_sock == -1) {
        ErrorHandling("socket() error");
    }

    struct sockaddr_in serv_addr; // allocate ip, port
    memset(&serv_addr, 0, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(atoi(argv[1]));

    if (bind(Serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1){ 
        ErrorHandling("bind() error");
    }

    if (listen(Serv_sock, 5) == -1) { // ready
        ErrorHandling("listen() error");
    }

    struct sockaddr_in clnt_addr;
    int clnt_addr_size = sizeof(clnt_addr);

    for (int i = 0; i < 5; ++i) {
        int Clnt_sock = accept(Serv_sock, (struct sockaddr*) &clnt_addr, &clnt_addr_size);  // accept
        if (Clnt_sock == -1){
            ErrorHandling("accept() error");
        }
        else{
            printf("Connected client %d \n", i+1);
        }

        while(1) {
            int over = 0, recv_len = 0, msg_len, recv_cnt;
            char msg[BUF_SIZE];
            while (recv_len == 0 || recv_len < msg_len + Len_SIZE) {
                recv_cnt = recv(Clnt_sock, (char*)&msg[recv_len], BUF_SIZE, 0);
                if (recv_cnt == -1) {
                    ErrorHandling("read() error!");
                }
                if (recv_cnt == 0) {
                    over = 1;
                    break;
                }
                recv_len += recv_cnt;
                if (recv_len >= Len_SIZE) {
                    memcpy(&msg_len, msg, Len_SIZE);
                }
            }
            msg[recv_len] = '\0';

            if (over == 1) {
                break;
            }

            printf("Message from client: %s", msg + Len_SIZE); // output message from client
            fputs("Input message: ", stdout);
            fgets(msg + Len_SIZE, BUF_SIZE - Len_SIZE, stdin); // input message
            int len = strlen(msg + Len_SIZE);
            memcpy(msg, &len, Len_SIZE);
            send(Clnt_sock, msg, Len_SIZE + len, 0); // send message to client
        }
        closesocket(Clnt_sock);
    }

    closesocket(Serv_sock);
    return 0;
}

1-2--客户端

// gcc string_client_win.c -o string_client_win -lwsock32
// string_client_win 127.0.0.1 9190

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#define BUF_SIZE 1024
#define Len_SIZE 4

void ErrorHandling(char *message){
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char* argv[]){

    if (argc != 3) {
        printf("Usage: %s <IP> <port>\n", argv[0]);
	    exit(1);
    }

    WSADATA wsaData; // init socket lib
    if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){
        ErrorHandling("WSAStartup() error!");
    }
    int sock = socket(PF_INET, SOCK_STREAM, 0);   // create socket
    if (sock == -1)
        ErrorHandling("socket() error");

    struct sockaddr_in serv_addr; // allocate ip, port
    memset(&serv_addr, 0, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
    serv_addr.sin_port = htons(atoi(argv[2]));

    if (connect(sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1){ // connect
        ErrorHandling("connect() error");
    }
    else {
        puts("Connected");
    }

    for(int i = 0; i < 3; i++) {
        char msg[BUF_SIZE];
        memset(msg, 0, BUF_SIZE);
        
        fputs("Input message: ", stdout);
        fgets(msg + Len_SIZE, BUF_SIZE - Len_SIZE, stdin); // input message
        int len = strlen(msg + Len_SIZE);
        memcpy(msg, &len, Len_SIZE);
        send(sock, msg, Len_SIZE + len, 0); // send message to server

        int recv_len = 0, msg_len = 0, recv_cnt = 0;
        while (recv_len == 0 || recv_len < msg_len + Len_SIZE) {
            recv_cnt = recv(sock, (char*)&msg, BUF_SIZE, 0);
            recv_len += recv_cnt;
            if (recv_len >= Len_SIZE) {
                memcpy(&msg_len, msg, Len_SIZE);
            }
        }
        msg[recv_len] = '\0';
        printf("Message from server: %s", msg + Len_SIZE);
    }

    closesocket(sock);
    return 0;
}

1-3--编译运行

# 服务器端
gcc string_server_win.c -o string_server_win -lwsock32
string_server_win 9190

# 客户端
gcc string_client_win.c -o string_client_win -lwsock32
string_client_win 127.0.0.1 9190

1-4--基于 linux 实现

项目链接:Chapter5

2--基于TCP实现文件传输

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

《TCP/IP网络编程》--基于TCP实现字符串对话和文件传输 的相关文章

随机推荐

  • bootstrap table复选框选多页勾选

    bootstrap table复选框选多页勾选 在项目中发现 bootstrap table的复选框选中后 翻页操作会导致上一页选中的丢失 api中的 bootstrapTable getSelections 只能拿到当前页的复选框 js
  • 正则表达式大全

    1 匹配中文 u4e00 u9fa5 2 英文字母 a zA Z 3 数字 0 9 4 匹配中文 英文字母和数字及下划线 u4e00 u9fa5 a zA Z0 9 同时判断输入长度 u4e00 u9fa5 a zA Z0 9 4 10 5
  • (Java)leetcode-236 Lowest Common Ancestor of a Binary Tree(二叉树的最近公共祖先)

    题目描述 给定一个二叉树 找到该树中两个指定节点的最近公共祖先 百度百科中最近公共祖先的定义为 对于有根树 T 的两个结点 p q 最近公共祖先表示为一个结点 x 满足 x 是 p q 的祖先且 x 的深度尽可能大 一个节点也可以是它自己的
  • MTK多国语言相关经验总结

    MTK多国语言相关经验总结 一 移植多国语言移植多国语言主要牵涉到对mmi features h 整个工程的宏控定义文件 fontres c 字体资源文件 的修改 并添加相应的字库文件 1 语言宏控的修改在mmi features h文件中
  • 使用C#语言,基于OpenCvSharp 开发摄像头后台,移动物体位置识别 (一)

    刚刚入门OpenCvSharp 也是小白一枚 教程很少 慢慢摸索 边学边记录 文末附链接 效果 要求 Visual Studio 2017 摄像头x1 准备工作 新建一个 Net Framework 控制台应用 右击解决方案 gt 管理解决
  • 京城游戏人-Day13: 获取被点击的 Button 以及其上的文字内容

    京城游戏人 Day13 获取被点击的 Button 以及其上的文字内容 作者 大锐哥 地址 http blog csdn net prevention 获取被点击的 button var button UnityEngine EventSy
  • Centos + docker,Ubuntu + docker介绍安装及详细使用

    docker笔记 常用命令 设置docker开机自启 sudo chkconfig docker on 查所有镜像 docker images 删除某个镜像 docker rmi CONTAINER ID 容器ID 删除所有镜像 docke
  • Linux命令大全!

    系统信息 arch 显示机器的处理器架构 1 uname m 显示机器的处理器架构 2 uname r 显示正在使用的内核版本 dmidecode q 显示硬件系统部件 SMBIOS DMI hdparm i dev hda 罗列一个磁盘的
  • Grid 布局实现九宫格图片动画

    前言 Grid 布局实现九宫格 background position设置背景图像起始位置 速速来Get吧 文末分享源代码 记得点赞 关注 收藏 1 实现效果 2 实现步骤 定义css变量 九宫格中每个宫格的长 宽为w 宫格之间的间距为ga
  • STL容器的线程安全

    众所周知 STL容器不是线程安全的 对于vector 即使写方 生产者 是单线程写入 但是并发读的时候 由于潜在的内存重新申请和对象复制问题 会导致读方 消费者 的迭代器失效 实际表现也就是招致了core dump 另外一种情况 如果是多个
  • firefox os_如何在电视上测试Firefox OS应用

    firefox os One of my responsibilities in my new role in Partner Engineering at Mozilla is testing HTML5 powered apps and
  • 解决git中出现的“bash syntax error near unexpected token ’(‘”错误

    今天来分享一篇关于我在git使用过程中出现的一个错误 错误信息 bash syntax error near unexpected token 翻译过来就是提示我在 这里有错误 而这个错误是我在使用git commit提交时候产生的 我当时
  • 4. Docker 构建镜像

    Docker 构建镜像 docker制作镜像通常是通过两种方式来实现的 第一种是通过容器的 commit 第二种是通过 Buildfile来实现的 docker commit 打包镜像 容器在运行过程中我们难免会做一些修改 比如运行的mys
  • 程序框架---缩进(Python)

    缩进 类定义 函数定义 选择结构 循环结构 with块 行尾的冒号表示缩进的开始 python程序是依靠代码块的缩进来体现代码之间的逻辑关系的 缩进结束就表示一个代码块结束了 同一级别代码块的缩进量必须相同 一般而言 以4个空格或一个TAB
  • OLED透明屏:在广告领域中的应用,为品牌注入更强的视觉冲击

    OLED透明屏作为一项引人注目的技术创新 其独特的透明度和高清晰度为各行各业带来了全新的展示和创意空间 本文将详细介绍其透明度 高对比度 超薄柔性设计以及强大的颜色表现力 并探讨其在零售 汽车和建筑等领域的应用前景 一 透明度 开启全新的透
  • 聊透spring @Configuration配置类

    本章节我们来探索Spring中一个常用的注解 Configuration 我们先来了解一下该注解的作用是 用来定义当前类为配置类 那啥是配置类啊 有啥用啊 这个我们得结合实际使用场景来说 通常情况下 加了 Configuration的配置类
  • 机器学习——决策树(Decision Trees)

    决策树 决策树是机器学习中一种最为常见的算法 顾名思义 决策树是基于树结构来进行决策的 这恰是人类在面对决策问题时一种很自然的处理机制 决策树的生成算法可以说是信息论的一种应用 但它其实只用到了信息论中的一小部分思想 因此对信息论有个基础性
  • Python系列教程-目录

    转载至 http www cricode com 3086 html Python初级教程 Python快速教程 手册 Python基础01 Hello World Python基础02 基本数据类型 Python基础03 序列 Pytho
  • CSS 之层叠规则(权级、权重、顺序)详解

    文章目录 参考 描述 定义 层叠 层叠与冲突 规则 权重 优先级 权重值的叠加 顺序 权级 权级 层叠规则的运用 顺序 尾声 参考 项目 描述 MDN WEB Docs 优先级 Amily mo 令人烦恼的css选择器权值问题 Amily
  • 《TCP/IP网络编程》--基于TCP实现字符串对话和文件传输

    1 基于TCP实现字符串对话 主要需求 服务器端和客户端各传递 1 次字符串 基于 TCP 协议 传递字符串前先以 4 字节整数型方式传递字符串长度 剩余部分为字符串数据 注 下面的代码基于 Windows 系统实现 1 1 服务器端 gc