服务端和客户端通信-TCP(含完整源代码)

这篇具有很好参考价值的文章主要介绍了服务端和客户端通信-TCP(含完整源代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简单TCP通信实验

目录

简单TCP通信实验

分析

1、套接字类型

2、socket编程步骤

3、socket编程实现具体思路

实验结果截图

程序代码


实验设备:   

目标系统:windows

软件工具:vs2022/VC6/dev

实验要求:

  1. 完成TCP服务端和客户端的程序编写;
  2. 实现简单字符串的收发功能。
  3. 需附上代码及运行结果截图。

实验内容:

分析:

1套接字类型

  ① 流式套接字(SOCK_STREAM): 提供面向连接的、可靠的字节流服务,用于TCP。

  ② 数据报套接字(SOCK_DGRAM): 提供无连接的,不可靠的数据报服务,用于UDP。

  ③ 原始套接字(SOCK_RAW): 允许对较低层的协议,如IP、ICMP直接访问。

复习TCP三次握手过程,理解TCP socket编程。

2、socket编程步骤

服务器端:

创建socket----socket()

绑定的socket和端口号------bind()

监听该端口号----listen()

接收来自客户端的连接请求---accept()

从socket中读取字符----recv()

关闭socket---close()

客户端:

创建socket-----socket()

连接指定计算机的端口-----connect()

向socket中写入信息-----send()

关闭socket-----close()

3、socket编程实现具体思路

服务器端:

其过程是首先服务器方要先启动,并根据请求提供相应服务

    1)打开一通信通道并告知本地主机,它愿意在某一公认地址上的某端口接收客户请求;

    2)等待客户请求到达该端口;

    3)接收到客户端的服务请求时,处理该请求并发送应答信号。接收到并发服务请求,要激活一新进程来处理这个客户请求。新进程处理此客户请求,并不需要对其它请求作出应答。服务完成后,关闭此新进程与客户的通信链路,并终止。

    4)返回第(2)步,等待另一客户请求。

    5)关闭服务器

客户端:

  1. 打开一通信通道,并连接到服务器所在主机的特定端口;
  2. 向服务器发服务请求报文,等待并接收应答;继续提出请求…
  3. 请求结束后关闭通信通道并终止。
  1. 代码实现过程分析

1)、创建套接字----socket()

应用程序在使用套接字前,首先必须拥有一个套接字,系统调用socket()向应用程序提供创建套接字的手段,其调用格式如下:

SOCKET PASCAL FAR socket(int af, int type, int protocol)

该调用要接收三个参数:af、type、protocol。

Af--------指定通信发生的区域:AF_UNIX、AF_INET、AF_NS等,而DOS、WINDOWS中仅支持AF_INET,它是网际网区域。因此,地址族与协议族相同。

Type----- 描述要建立的套接字的类型。这里分三种:

一、是TCP流式套接字(SOCK_STREAM)提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复地发送,且按发送顺序接收。内设流量控制,避免数据流超限;数据被看作是字节流,无长度限制。文件传送协议(FTP)即使用流式套接字。

二、是数据报式套接字(SOCK_DGRAM)提供了一个无连接服务。数据包以独立包形式被发送,不提供无错保证,数据可能丢失或重复,并且接收顺序混乱。网络文件系统(NFS)使用数据报式套接字。

三、是原始式套接字(SOCK_RAW)该接口允许对较低层协议,如IP、ICMP直接访问。常用于检验新的协议实现或访问现有服务中配置的新设备。

Protocol-----说明该套接字使用的特定协议,如果调用者不希望特别指定使用的协议,则置为0,使用默认的连接模式。

服务端和客户端通信-TCP(含完整源代码)

服务端和客户端通信-TCP(含完整源代码)

2)指定本地地址---bind()

当一个套接字用socket()创建后,存在一个名字空间(地址族),但它没有被命名。bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字号联系起来,即将名字赋予套接字,以指定本地半相关。其调用格式如下:

int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR * name, int namelen); 

s----是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。
name-----是赋给套接字s的本地地址(名字),其长度可变,结构随通信域的不同而不同。
namelen-----表明了name的长度。如果没有错误发生,bind()返回0。否则返回SOCKET_ERROR。

服务端和客户端通信-TCP(含完整源代码)

3)建立套接字连接---connect()与accept()

这两个系统调用用于完成一个完整相关的建立,其中connect()用于建立连接。accept()用于使服务器等待来自某客户进程的实际连接。connect()的调用格式如下:

int PASCAL FAR connect(SOCKET s, const struct sockaddr FAR * name, int namelen);

参数s是欲建立连接的本地套接字描述符。
参数name指出说明对方套接字地址结构的指针。
对方套接字地址长度由namelen说明。
如果没有错误发生,connect()返回0。否则返回值SOCKET_ERROR。在面向连接的协议中,该调用导致本地系统和外部系统之间连接实际建立。、

服务端和客户端通信-TCP(含完整源代码)

accept()的调用格式如下:

SOCKET PASCAL FAR accept(SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen); 

参数s为本地套接字描述符,在用做accept()调用的参数前应该先调用过listen()。

addr指向客户方套接字地址结构的指针,用来接收连接实体的地址。addr的确切格式由套接字创建时建立的地址族决定。

addrlen为客户方套接字地址的长度(字节数)。

如果没有错误发生,accept()返回一个SOCKET类型的值,表示接收到的套接字的描述符。否则返回值INVALID_SOCKET。

服务端和客户端通信-TCP(含完整源代码)

4)监听连接---listen()

此调用用于面向连接服务器,表明它愿意接收连接。listen()需在accept()之前调用,其调用格式如下:

int PASCAL FAR listen(SOCKET s, int backlog);

参数s标识一个本地已建立、尚未连接的套接字号,服务器愿意从它上面接收请求。

backlog表示请求连接队列的最大长度,用于限制排队请求的个数,目前允许的最大值为5。

如果没有错误发生,listen()返回0。否则它返回SOCKET_ERROR。

listen()在执行调用过程中可为没有调用过bind()的套接字s完成所必须的连接,并建立长度为backlog的请求连接队列。

5)数据传输---send()与recv()

当一个连接建立以后,就可以传输数据了。常用的系统调用有send()和recv()。
send()调用用于s指定的已连接的数据报或流套接字上发送输出数据,格式如下:

int PASCAL FAR send(SOCKET s, const char FAR *buf, int len, int flags);

参数s为已连接的本地套接字描述符。
buf 指向存有发送数据的缓冲区的指针,其长度由len 指定。
flags指定传输控制方式,如是否发送带外数据等。如果没有错误发生,
send()返回总共发送的字节数。否则它返回SOCKET_ERROR。

服务端和客户端通信-TCP(含完整源代码)

服务端和客户端通信-TCP(含完整源代码)

recv()调用用于s指定的已连接的数据报或流套接字上接收输入数据,格式如下:

int PASCAL FAR recv(SOCKET s, char FAR *buf, int len, int flags);

参数s 为已连接的套接字描述符。
buf指向接收输入数据缓冲区的指针,其长度由len 指定。
flags指定传输控制方式,如是否接收带外数据等。
如果没有错误发生,recv()返回总共接收的字节数。如果连接被关闭,返回0。否则它返回SOCKET_ERROR。

服务端和客户端通信-TCP(含完整源代码)

6)关闭套接字---closesocket()

closesocket()关闭套接字s,并释放分配给该套接字的资源;如果s涉及一个打开的TCP连接,则该连接被释放。closesocket()的调用格式如下:

BOOL PASCAL FAR closesocket(SOCKET s);

参数s待关闭的套接字描述符。
如果没有错误发生,closesocket()返回0。否则返回值SOCKET_ERROR。

服务端和客户端通信-TCP(含完整源代码)

注意:client_in.sin_addr.S_un.S_addr = inet_addr()

inet_addr()地址要查询本机的ip。或者直接用回环地址127.0.0.1

服务端和客户端通信-TCP(含完整源代码)

服务端和客户端通信-TCP(含完整源代码)

实验结果截图:

服务端和客户端通信-TCP(含完整源代码)

 服务端和客户端通信-TCP(含完整源代码)

 

程序代码:

客户端:

#include<stdio.h>

#include <Winsock2.h>

#pragma comment(lib, "Ws2_32.lib")

#include<windows.h>

int main()

{

  char sendBuf[1024];

  char receiveBuf[1024];

  while (1)

  {

        WSADATA wsadata;

        if (0 == WSAStartup(MAKEWORD(2, 2), &wsadata))

        {

              printf("等待连接....\n");

             

        }

        else

        {

                    printf("连接失败!\n");

 

        }

        SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);

        SOCKADDR_IN client_in;

        client_in.sin_addr.S_un.S_addr = inet_addr("172.29.18.16");//将网络地址字符串转换成二进制形式

        client_in.sin_family = AF_INET;

        client_in.sin_port = htons(6000);

        connect(clientSocket, (SOCKADDR*)&client_in, sizeof(SOCKADDR));

        recv(clientSocket, receiveBuf, 1024, 0);

        printf("收到来自服务器:  %s\n", receiveBuf);

      printf("向服务器发出: ");

        gets(sendBuf);

        send(clientSocket, sendBuf, 1024, 0);

        closesocket(clientSocket);

        WSACleanup();

  }

  return 0;

}文章来源地址https://www.toymoban.com/news/detail-471455.html

服务端:

#include<stdio.h>

#include <Winsock2.h>

#pragma comment(lib, "Ws2_32.lib")

#include<windows.h>

int main()

{

  char sendBuf[1024];

  char receiveBuf[1024];

  while (1)

  {

        //创建套接字,socket前的一些检查工作.

  //服务的启动

        WSADATA wsadata;//wsa 即windows socket async 异步套接字

        if (0 != WSAStartup(MAKEWORD(2, 2), &wsadata))

        {

              printf("未连接\n");

              return 0;

        }

        else

        {

              printf("连接成功!\n");

        }

       SOCKET serSocket = socket(AF_INET, SOCK_STREAM, 0);//创建可识别的套接字//parm1: af 地址协议族 ipv4 ipv6

                                                           //parm2:type 传输协议类型 流式套接字(SOCK_STREAM),数据包套接字(SOCK_DGRAM)

                                                           //parm3:ptotoc1 使用具体的某个传输协议

       

        SOCKADDR_IN addr;                                  //需要绑定的参数,主要是本地的socket的一些信息。

        addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);     //ip地址,htonl即host本机 to:to  n:net l:unsigned long 大端存储,低字节在高位

        addr.sin_family = AF_INET;

        addr.sin_port = htons(6000);                       //端口 htons将无符号短整型转化为网络字节序

        bind(serSocket, (SOCKADDR*)&addr, sizeof(SOCKADDR));

        listen(serSocket, 5);                             

        SOCKADDR_IN clientsocket;

        int len = sizeof(SOCKADDR);

        SOCKET serConn = accept(serSocket, (SOCKADDR*)&clientsocket, &len);

        printf("向客户端发出: \n");

        gets(sendBuf);

        send(serConn, sendBuf, 1024, 0);

        recv(serConn, receiveBuf,1024, 0);

 

        printf("收到来自客户端: %s\n", receiveBuf);

        closesocket(serConn);//关闭

        WSACleanup();//释放资源

  }

  return 0;

}

到了这里,关于服务端和客户端通信-TCP(含完整源代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • UDP服务端和客户端通信代码开发流程

    TCP: 传输控制协议,面向连接的,稳定的,可靠的,安全的数据集流传递 稳定和可靠:丢包重传 数据有序:序号和确认序号 流量控制:稳定窗口 UDP :用户数据报协议 面向无连接的,不稳定的,不可靠,不安全的数据报传递=---更像是收发短信,UDP传输不需要建立连接,传输效率更高

    2024年02月06日
    浏览(33)
  • 网络编程——socket服务端和客户端(TCP)

    所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通

    2024年02月07日
    浏览(34)
  • Golang实现之TCP长连接-------服务端和客户端

    一、数据包的数据结构 (所有字段采用大端序) 帧头 帧长度(头至尾) 帧类型 帧数据 帧尾 1字节 4字节 2字节 1024字节 1字节 byte int short string byte 0xC8 0xC9 二、Server端 实现代码 1、main.go 2、server.go 3、protocol.go 4、response.go 5、result.go 三、Client端 实现代码

    2024年02月07日
    浏览(37)
  • SpringBoot搭建Netty+Socket+Tcp服务端和客户端

    yml配置:    完成,启动项目即可自动监听对应端口 这里为了测试,写了Main方法,可以参考服务端,配置启动类 ,实现跟随项目启动   ......想写就参考服务端...... 有测试的,,,但是忘记截图了................

    2024年02月15日
    浏览(43)
  • 网络编程3——TCP Socket实现的客户端服务器通信完整代码(详细注释帮你快速理解)

    本人是一个刚刚上路的IT新兵,菜鸟!分享一点自己的见解,如果有错误的地方欢迎各位大佬莅临指导,如果这篇文章可以帮助到你,劳请大家点赞转发支持一下! 今天分享的内容是TCP流套接字实现的客户端与服务器的通信,一定要理解 DatagramSocket,DatagramPacket 这两个类的作用以及方法

    2024年02月12日
    浏览(44)
  • 《TCP/IP网络编程》阅读笔记--基于Windows实现Hello Word服务器端和客户端

    目录 1--Hello Word服务器端 2--客户端 3--编译运行 3-1--编译服务器端 3-2--编译客户端 3-3--运行 运行结果:

    2024年02月10日
    浏览(43)
  • tcp通信,客户端服务端

    //TCP通信的流程 //服务器端(被动接受连接的角色) 1.创建一个用于监听的套接字         -监听:监听有客户端的连接         -套接字:这个套接字其实就是一个文件描述符 2.将这个监听文件描述符和本地的IP和端口绑定(IP和端口就是服务器的地址信息)         -客户端

    2024年02月09日
    浏览(30)
  • TCP实现服务器和客户端通信

    目录 TCP介绍 代码实现 server(服务器端) 代码分析 client(客户端) 代码分析 结果展示 TCP (Transmission Control Protocol) 是一种面向连接的协议,用于在计算机网络中传输数据。TCP 可以确保数据的可靠传输,即使在网络环境不稳定的情况下也能够保证数据的完整性和顺序。以下是

    2024年02月15日
    浏览(44)
  • QTday05(TCP的服务端客户端通信)

    pro文件需要导入  network 头文件: widget.cpp ui: 头文件 widget.cpp ui: 运行结果:客户端连接之后可以成功发送信息 今日思维导图: 代码: page2.h: widget.h: main.cpp: page2.cpp: widget.cpp: page2.ui: widget.ui: 运行结果:

    2024年02月07日
    浏览(28)
  • 简易TCP客户端和服务器端通信

    #includeiostream #include winsock2.h   #include ws2tcpip.h   #includestdlib.h using namespace std; #define  BUF_SIZE  1024 int main() {     cout \\\"客户端\\\" endl;     //设置Winsock版本,     WSADATA   wsaData;     if (WSAStartup(MAKEWORD(2, 2), wsaData) != 0)     {         cout \\\"error\\\" endl;         exit(1);     }     //创建通

    2024年04月29日
    浏览(34)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包