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

这篇具有很好参考价值的文章主要介绍了《TCP/IP网络编程》--基于TCP实现字符串对话和文件传输。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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文章来源地址https://www.toymoban.com/news/detail-699345.html

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

到了这里,关于《TCP/IP网络编程》--基于TCP实现字符串对话和文件传输的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • TCP IP网络编程(五) 基于TCP的服务器端、客户端 (补充)

    回声客户端出现的问题 在上一节基于TCP的服务器端、回声客户端中,存在问题: 如果数据太大,操作系统就有可能把数据分成多个数据包发送到客户端,客户端有可能在尚未收到全部数据包时就调用read函数 问题出在客户端,而不是服务器端,先来对比一下客户端与服务器端

    2024年02月09日
    浏览(54)
  • 《TCP/IP网络编程》阅读笔记--基于TCP的服务器端/客户端

    目录 1--TCP/IP协议栈 2--TCP服务器端默认函数调用顺序 3--TCP客户端的默认函数调用顺序 4--Linux实现迭代回声服务器端/客户端 5--Windows实现迭代回声服务器端/客户端 6--TCP原理 7--Windows实现计算器服务器端/客户端         TCP/IP协议栈共分 4 层,可以理解为数据收发分成了 4 个层

    2024年02月10日
    浏览(49)
  • Linux网络编程:IP地址的字符串与网络字节序转换:inet_addr()、inet_aton()、inet_ntoa()、inet_pton()、inet_ntop()

    IP地址的字符串与网络字节序转换 向sockaddr_in注入地址时,需要将ip地址的字符串形式转化为网络字节序的形式;而相反地,网络字节序也能转化回字符串形式。用到的函数分别inet_addr()、inet_aton()、inet_ntoa()、inet_pton()、inet_ntop(),转化的方向如下图。 1 inet_addr() 功能:是将一

    2024年02月03日
    浏览(36)
  • Linux网络编程——C++实现进程间TCP/IP通信

    地址接口 1、通用地址接口 共16字节 = 2字节地址类型 + 14字节地址数据 2、自定义地址接口 地址转换 1、需要将点分字符串ip转化为程序ip,使用inet_addr函数: 2、字节序转换 地址接口配置中的端口需要字节序转换,网络规定使用大端字节序。 地址接口配置 1、socket:创建套接

    2024年02月20日
    浏览(45)
  • 《TCP/IP网络编程》阅读笔记--基于UDP的服务器端/客户端

    目录 1--TCP和UDP的主要区别 2--基于 UDP 的数据 I/O 函数 3--基于 UDP 的回声服务器端/客户端 4--UDP客户端Socket的地址分配 5--UDP存在数据边界 6--UDP已连接与未连接的设置 ① TCP 提供的是可靠数据传输服务,而 UDP 提供的是不可靠数据传输服务; ② UDP 在结构上比 TCP 更简洁,其不会

    2024年02月09日
    浏览(52)
  • Socket网络编程(TCP/IP)实现服务器/客户端通信。

    一.前言 回顾之前进程间通信(无名管道,有名管道,消息队列,共享内存,信号,信号量),都是在同一主机由内核来完成的通信。 那不同主机间该怎么通信呢? 可以使用Socket编程来实现。 Socket编程可以通过网络来实现实现不同主机之间的通讯。 二.Socket编程的网络模型如

    2024年02月08日
    浏览(74)
  • Linux网络编程之TCP/IP实现高并发网络服务器设计指南

    目录 引言: 多进程服务器 例程分享: 多线程服务器  例程分享: I/O多路复用服务器 select 例程分享: poll 例程分享: epoll 例程分享: 总结建议         随着互联网的迅猛发展,服务器面临着越来越多的并发请求。如何设计一个能够高效处理大量并发请求的服务器成为

    2024年02月20日
    浏览(46)
  • 基于UDP/TCP的网络通信编程实现

    红色是心中永不褪色的赤诚 操作系统为网络编程提供了 Socket api , Socket是基于TCP/IP协议的网络通信的基本单元, 基于Socket的网络程序开发就是 网络编程. 由于直接与应用层联系的是传输层, 所以针对应用层协议(TCP, UDP), Shocket提供了三种套接字, 分别是 流套接字(使用TCP) , 数据报

    2024年02月08日
    浏览(43)
  • 基于数据库及TCP网络编程实现的电子词典

    目录 一、前言 二、项目介绍 三、功能实现 3.1. 用户注册 3.1.1 功能演示 3.1.2 功能函数实现 3.2. 用户登录 3.2.1 功能演示 3.2.2 功能函数实现 3.3. 查询单词 3.3.1 功能演示 3.3.2 功能函数实现 3.4. 历史查询 3.4.1 功能演示 3.4.2 功能函数实现 四、代码实现 4.1 服务器程序 server.c 4.2 客户

    2023年04月09日
    浏览(74)
  • 《TCP IP网络编程》

            2023.6.28 正式开始学习网络编程。 每一章每一节的笔记都会记录在博客中以便复习。         网络编程又叫套接字编程。所谓网络编程,就是编写程序使两台连网的计算机相互交换数据。 为什么叫套接字编程? 我们平常将插头插入插座上就能从电网中获取电力,同

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包