基于TCP的客户端、服务器端socket编程

基于TCP协议实现服务器和客户端的通信程序 实习期间,项目要求学习MFC编程和SOCKET编程,先写了一个入门的小程序来熟悉一下。 服务器的界面图: 为了简化,将服务器的IP和Port固定为127.0.0.1和5000 【启动】按钮用来启动服务器 代码: void CServerDlg::OnBnClickedStartButton() { // TODO: 在此添加控件通知处理程序代码 if(0 != WSASt 阅读详情

基于TCP的客户端、服务器端socket编程

一、实验目的

理解tcp传输客户端服务器端通信流程

二、实验平台

MAC OS
gxx-include-dir=/usr/include/c++/4.2.1

三、实验内容

编写TCP服务器套接字程序,程序运行时服务器等待客户的连接,一旦连接成功,则显示客户的IP地址、端口号,并向客户端发送字符串。

四、实验原理

使用TCP套接字编程可以实现基于TCP/IP协议的面向连接的通信,它分为服务器端和客户端两部分,其主要实现过程如下
process

1、socket函数
在网络编程中所需要进行的第一件事情就是创建一个socket,无论是客户端还是服务器端,都需要创建一个socket,该函数返回socket文件描述符,类似于文件描述符。socket是一个结构体,被创建在内核中。

    sockfd=socket(AF_INET,SOCK_STREAM,0);   //AF_INT:ipv4, SOCK_STREAM:tcp协议

2、connect函数
客户端创建了socket后,需要和服务器端建立连接,此时使用connect函数和服务器端进行连接。

    connect(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))
  • 三次握手:
  • 第一次握手:客户端发送syn包(syn=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
  • 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
  • 握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。

3、bind函数
把一个本地协议地址和套接口绑定,比如把本机的2222端口绑定到套接口。注意:为什么在上图中客户端不需要调用bind函数?这是因为如果没有调用bind函数绑定一个端口的话,当调用connect函数时,内核会为该套接口临时选定一个端口,因此可以不用绑定。而服务器之所以需要绑定的原因就是,所以客户端都需要知道服务器使用的哪个端口,所以需要提前绑定。

    bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))

4、listen函数
当socket创建后,它通常被默认为是主动套接口,也就是说是默认为要马上调用connect函数的,而作为服务器是需要被动接受的,所以需要调用linsten函数将主动套接口转换成被动套接口。调用linsten函数后,内核将从该套接口接收连接请求。

   /**
     * 3:调用listen函数监听(指定port监听)
     * 通知操作系统区接受来自客户端链接请求
     * 第二个参数:指定队列长度
     */

    if(listen(sockfd,10) < 0)
    {
        perror("listen error");
    }

5、accept函数
此函数返回已经握手完成的连接的套接口。注意:此处的套接口不同于服务器开始创建的监听套接口,此套接口是已经完成连接的套接口,监听套接口只是用来监听。

    accept(sockfd,(struct sockaddr*)&clientaddr,&clientaddr_len);

6、write函数
调用IO函数(read/write)和连接的客户端进行双向通信。

    long t = time(0);
    char *s = ctime(&t);
    size_t size = strlen(s) * sizeof(char);
    //将服务器的系统时间写到客户端
    if(write(fd,s,size) != size)
    {
        perror("write error");
    }

7、close函数
数据传输完成后,需要关闭套接口

    //关闭socket
    close(fd);

linux网络编程之用一张图片说明套接口常用函数

API

五、实验流程

  • 服务器端代码
#include "iostream"
#include "netdb.h"
#include "stdio.h"
#include "stdlib.h"
#include "sys/socket.h"
#include "unistd.h"
#include "arpa/inet.h"
#include "string.h"
#include "memory.h"
#include "signal.h"
#include "time.h"

using namespace std;

int sockfd;

void sig_handler(int signo)
{
    if(signo == SIGINT)
    {
        cout<<"Server close"<<endl;
        close(sockfd);
        exit(1);
    }
}

//输出链接上来的客户端相关信息
void out_addr(struct sockaddr_in *clientaddr)
{
    //将断口从网络字节序转成主机字节序
    int port = ntohs(clientaddr->sin_port);
    char ip[16];
    memset(ip,0,sizeof(ip));
    inet_ntop(AF_INET,&clientaddr->sin_addr.s_addr,ip,sizeof(ip));
    cout<<"client:"<<ip<<"("<< port <<")connected\n"<<endl;
}

void do_service(int fd)
{
    //获取系统时间
    long t = time(0);
    char *s = ctime(&t);
    size_t size = strlen(s) * sizeof(char);
    //将服务器的系统时间写到客户端
    if(write(fd,s,size) != size)
    {
        perror("write error");
    }
}

int main(int argc,char *argv[])
{
    if(argc<2)
    {
        cout<<"usage:"<<argv[0]<<"#port"<<endl;
        exit(1);
    }

    if(signal(SIGINT,sig_handler) == SIG_ERR)
    {
        perror("signal sigint error");
        exit(1);
    }

    /**
     * 1.创建socket
     * AF_INET:ipv4
     * SOCK_STRAM:tcp协议
     */
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        perror("socket error");
        exit(1);
    }

    //2.调用bind函数绑定socket和地址

    struct sockaddr_in serveraddr;
    memset(&serveraddr,0,sizeof(serveraddr));
    //往地址中填入ip,port,internet类型
    serveraddr.sin_family = AF_INET;    //ipv4
    serveraddr.sin_port = htons(atoi(argv[1])); //htons主机字节序转成网络字节序

    serveraddr.sin_addr.s_addr = INADDR_ANY;

    if(bind(sockfd,(struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
    {
        perror("bind error");
        exit(1);
    }

    /**
     * 3:调用listen函数监听(指定port监听)
     * 通知操作系统区接受来自客户端链接请求
     * 第二个参数:指定队列长度
     */

    if(listen(sockfd,10) < 0)
    {
        perror("listen error");
    }

    /**
     * 4:调用accept函数从队列中
     * 获得一个客户端的请求链接
     */

    struct sockaddr_in clientaddr;
    socklen_t clientaddr_len = sizeof(clientaddr);

    while(1)
    {
        int fd = accept(sockfd,(struct sockaddr*)&clientaddr,&clientaddr_len);
        if(fd < 0)
        {
            perror("accept error");
            continue;
        }

        /**
         * 5:调用IO函数(read/write)和
         * 连接的客户端进行双向通信
         */
        out_addr(&clientaddr);
        do_service(fd);

        //关闭socket
        close(fd);
    }

    return 0;
}
  • 客户端代码
#include "netdb.h"
#include "sys/socket.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "memory.h"
#include "unistd.h"
#include <arpa/inet.h>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    if(argc < 3)
    {
        cout<< "usage:"<<argv[0]<<" ip port"<<endl;
        exit(1);
    }

    //步骤1:创建socket
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        perror("socket error");
        exit(1);
    }

    struct sockaddr_in serveraddr;
    memset(&serveraddr,0,sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));

    //主机字节序转换成网络字节序
    inet_pton(AF_INET,argv[1],&serveraddr.sin_addr.s_addr);

    //步骤2:客户端调用connect函数连接到服务器
    if(connect(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr)) < 0)
    {
        perror("connect error");
        exit(1);
    }

    //步骤3:调用IO函数(read/write)和服务器端双向通信
    char buffer[1024];
    memset(buffer,0,sizeof(buffer));
    size_t size;

    if((size=read(sockfd,buffer,sizeof(buffer)))< 0)
    {
        perror("read error");
    }

    if(write(STDOUT_FILENO,buffer,size)!=size)
    {
        perror("write error");
    }

    return 0;
}

实验结果

实验结果

思考

  • 在进行网络通信时是否需要进行字节序转换:相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。

参考文献

TCP服务器端和客户端程序设计 一、实验目的 学习和掌握Linux下的TCP服务器基本原理和基本编程方法,体会TCP与UDP编程的不同,UDP编程:http://blog.youkuaiyun.com/yueguanghaidao/article/details/7055985 二、实验平台 Linux操作系统 三、实验内容 编写Linux下TCP服务器套接字程序,程序运行时服务器等待客户的连接,一旦连接成功,则显示客户的IP地址 阅读详情

相关推荐

使用socket编程实现服务器端与客户端(tcp)

服务器端socket。tcp创建服务器,使用的编译软件是vs//创建socketsocket tcpServer = new Socket(AddressFamily.InterNetwork,SocketType.stream,ProtocolType.Tcp);//AddressFamily.InterNetwork代表地址类型,SocketType.stream代表数据类型,Protocol...

qq_37118403的博客 2897

基于TCP协议的客户端/服务器程序

socket函数: int socket(int domain, int type, int protocol); socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符,应用程序可以像读写文件一样用read/write在网络上收发数据,如果socket()调用出错则返回-1。对于IPv4,domain参数指定为AF_INET。对于TCP协议,type参数指定为SOCK_STREAM,表示面向流的传输协议。如果是UDP协议,则type参数指定为SOCK_DGRAM,表示面

qq_44690575的博客 1061

C#socket编程——TCP协议创建服务器端和客户端并进行通信

我们做网络通信的时候需要有通信协议,在进行socket编程的时候有两种通信协议TCP、UDP,这次我们就用简单的方式在一台电脑建立TCP协议的服务器端和客户端并使之进行通信。 服务器端和客户端进行连接,第一步就行在服务器端创建一个socket,开始监听客户端的连接,然后在客户端创建一个socket,向服务器端发起连接,这样连接建立起来之后就可以进行数据的交换。 由于Visual Studio一...

Lenny的博客 1万+

基于TCP(面向连接)的socket编程

基于TCP(面向连接)的socket编程 一.基于TCP(面向连接)的socker编程的服务器端程序流程如下: (1) 创建套接字(socket) (2) 将套接字绑定到一个本地地址和端口上(bind) (3) 将套接字设置为监听模式,准备接收客户请求(listen) (4) 等待客户请求的到来;当客户请求到来后,接受连接请求,返回一个新的对...

weixin_34138056的博客 462

四阶龙格库塔法求解一次常微分方程组(python实现)

之前在博客发布了关于使用四阶龙格库塔方法求解一次常微分方程组的文章,由于代码缺少具体的验证,部分朋友可能存在疑问,因此这里打算再重新写一篇博客来验证一下程序的正确性,另外,这里是使用python语言来实现的。

HelloWorldTM的博客 8541

保研专业课复习别瞎卷!抓住408和数学重点,用真题反推高效复习路径

本文针对计算机专业保研学生,提出以真题为导向的408专业课和数学高效复习策略。通过构建真题知识图谱、分析题型与难度矩阵,帮助考生精准把握数据结构、操作系统等核心科目的高频考点,如树与图算法、TCP/IP协议栈等,并制定科学的时间分配方案,实现短期内的快速突破。

weixin_27966471的博客 402

C#编程 socket编程之tcp服务器端和客户端

基于Tcp协议的Socket通讯类似于B/S架构,面向连接,但不同的是服务器端可以向客户端主动推送消息。 使用Tcp协议通讯需要具备以下几个条件: (1).建立一个套接字(Socket) (2).绑定服务器端IP地址及端口号--服务器端 (3).利用Listen()方法开启监听--服务器端 (4).利用Accept()方法尝试与客户端建立一个连接--服务器端 (5).利用Connect...

Obliviate的博客 9161

uniapp+ucharts折线图toolTip不显示?别慌,手把手教你用showToolTip方法精准修复

本文详细解析了uniapp+ucharts折线图中toolTip不显示的常见问题,提供了showToolTip方法的精准修复方案。从底层原理到实战代码,帮助开发者解决触摸事件冲突、坐标计算偏差等问题,确保折线图交互提示功能稳定运行。

weixin_30316097的博客 401

java服务器端和客户端对话_JAVA网络编程 ——基于TCP的Socket编程—实现服务器端与客户端的实时对话...

一,HTTP与Socket1.HTTP:超文本传输协议特点:客户端发送的请求需要服务器端每次来响应,在请求结束之后主动释放连接,从建立连接到关闭连接称为“一次连接”,所以HTTP是“短连接”。2.Socket(IP+PORT):是TCP/IP的封装与应用,它不是协议,而是API特点:客户端与服务器之间一旦建立连接,就可以互相范松消息,也叫对话,但在实际应用中,通信双方经过许多的中间节点,比如,路由...

weixin_32821257的博客 732

【ComfyUI报错解决】K采样器 mat1和mat2形状不匹配错误分析与修复 mat1 and mat2 shapes cannot be multiplied (77x2048 and 4096x

如果你在 ComfyUI 里遇到K采样器报错:mat1 和 mat2 shapes cannot be multiplied确认大模型和 LoRA 是否是同一版本(SDXL vs SD1.5,不能混用)。如果用了双 CLIP 加载器,要确认加载的类型和选择的模型类型是否匹配。加载→ 类型选flux加载 SDXL 专用的 clip/t5 → 类型选sdxl避免不同版本模型和 LoRA 混搭,保持一致性。模型+LoRA+CLIP 类型必须保持同一版本,不然就会报错。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 2407

模拟一个基站和一个移动台之间的信号传播

同样使用时间序列和上述参数计算出反射径信号的信号强度。根据时间序列和上述参数,计算出直射径信号的信号强度。该信号被视为一个简单的正弦波信号,其频率是2Hz。:时间序列,从0.1秒开始,每隔0.0001秒采样一次,直到12秒。:设置坐标轴范围,横轴范围为0到12秒,纵轴范围为-0.5到0.5。:移动台移动的速度。:移动台距离基站的初始距离。:基站到反射墙的距离。假设基站到反射墙的距离为15米。:绘制直射径信号、反射径信号和合成信号的波形图。:添加标签,标注每条曲线对应的含义。表示反射径信号的颜色为绿色,

Fanjufei的博客 290

TCP的客户端、服务器端socket编程

使用TCP套接字编程可以实现基于TCP/IP协议的面向连接的通信,它分为服务器端和客户端两部分,其主要实现过程如下 : 1、socket函数 无论是客户端还是服务器端,都需要创建一个socket,该函数返回socket标识符。socket是一个结构体,被创建在内核中。 sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //AF_INT:ipv4, SOCK_STREAM:tcp协议 2、connect函数 客户端创建了socket后,需要和服务器端建立连

qq_34270874的博客 809

【DeepSeek-R1 】分词系统架构解析

DeepSeek-R1 分词系统解析 DeepSeek-R1 采用 SentencePiece Unigram 算法,通过统计语言模型实现高效子词分词。其核心优势包括: 算法对比:相比 BPE/WordPiece,Unigram 基于概率模型,支持多语言,自动回退字符级处理。 特性优化:智能空格处理、数字分桶、多语言统一支持,并采用前缀树索引和 SIMD 并行加速,编码速度达 12,458 tok/s。

赶紧的博客 429

基于Java的Socket网络编程,TCP通信,服务器端与客户端的单向通信

前言:TCP服务器端与客户端之间的交互过程如下:          1、服务器程序创建一个ServerSocket(服务器端套接字),并且调用ServerSocket里面的accept()方法来等待客户机的连接          2、客户端程序创建一个Socket(这个套接字里面包含了服务器的IP地址,以及端口号)与服务器连接          3、服务器端收到客户端的连接请求后,同时建立起一个新...

zjf的日常 2733

python ERA-5气象数据NetCDF格式解析(一)

python ERA-5气象数据NetCDF格式解析

weixin_43896283的博客 2637

4、海洋哺乳动物运动能量学:潜水与生存的奥秘

本文深入探讨了海洋哺乳动物在潜水与运动中的能量消耗机制,涵盖其生理反应、代谢成本、节能行为策略及测量方法。通过分析不同物种的能量利用特点,揭示了它们如何在极端水下环境中维持能量平衡,并讨论了该研究在保护生物学、生态系统动态和动物健康管理中的实际意义。文章还展望了未来多学科交叉、长期监测及应对环境变化的研究方向,为理解海洋哺乳动物的生存奥秘提供了系统性视角。

p5l2m9n4o6q的博客 116

java创建服务端类跟客户端类_JAVA网络编程 ——基于TCP的Socket编程(1)——实现服务器端与客户端的实时对话...

JAVA网络编程 ——基于TCP的Socket编程(1)——实现服务器端与客户端的实时对话发布时间:2018-03-17 13:38,浏览次数:324, 标签:JAVATCPSocket第一篇文章,我先介绍以及记录一下我所学的知识点。(总结了一下视频老师讲的东西)一,HTTP与Socket1.HTTP:超文本传输协议特点:客户端发送的请求需要服务器端每次来响应,在请求结束之后主动释放连接,从建立连...

weixin_32753181的博客 399

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Linux网络编程:socket、客户端服务器端使用socket通信(TCP)

Linux网络编程:socket、客户端服务器端使用socket通信(TCP)

坚持学习 4757

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

socket网络编程 java_java网络编程之socket网络编程示例(服务器端/客户端)

Java为TCP协议提供了两个类,分别在客户端编程和服务器端编程中使用它们。在应用程序开始通信之前,需要先创建一个连接,由客户端程序发起;而服务器端的程序需要一直监听着主机的特定端口号,等待客户端的连接。在客户端中我们只需要使用Socket实例,而服务端要同时处理ServerSocket实例和Socket实例;二者并且都使用OutputStream和InpuStream来发送和接收数据。学习一种知...

weixin_34536454的博客 238

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

JAVA网络编程 ——基于TCP的Socket编程(1)——实现服务器端与客户端的实时对话

第一篇文章,我先介绍以及记录一下我所学的知识点。(总结了一下视频老师讲的东西)一,HTTP与Socket1.HTTP:超文本传输协议特点:客户端发送的请求需要服务器端每次来响应,在请求结束之后主动释放连接,从建立连接到关闭连接称为“一次连接”,所以HTTP是“短连接”。2.Socket(IP+PORT):是TCP/IP的封装与应用,它不是协议,而是API特点:客户端与服务器之间一旦建立连接,就可以...

清风半夜鸣蛙 1万+
上一篇: [算法导论]网易MIT算法导论课笔记(简略版)
下一篇: 堆和栈的笔记
xy_cpp
博客等级 码龄10年 119粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值