首页 > 作文

Windows下VScode实现简单回声服务的方法

更新时间:2023-04-05 08:20:14 阅读: 评论:0

目录

1. 相关知识

1.1 什么是回声服务

回声服务端可以将客户端传来的信息,再原封不动地发送给客户端,因而得名 epoch 服务。服务端 rver 和 客户端 client 基于 tcp 进行通信。

1.2 服务端、客户端如何交互

下图给出了基于 tcp 的服务器端和客户端的交互过程。
首先服务端创建 socket 套接字,之后调用 bind 函数分配服务端 socket 地址,调用 listen 函数使服务端进入监听状态,同时维护一个半连接队列。服务端之后会调用 accept 函数,进入阻塞状态。accept 函数会从全连接的队列中取出一个连接进行处理。tcp 连接建立完成之后,服务端和客户端即可通过 nd 和 recv 发送和接收数据。
注意:服务端调用 listen 函数进入等待连接状态后,客户端才能调用 connect 函数发起连接请求。

服务端和客户端交互就是一种通信过程,它们基于 tcp 实现 socket 通信。tcp 协议中有三次握手、四次挥手的协议内容,如下图所示。

服务端和客户端通过三次握手建立连接,四次挥手断开连接。
具体到socket编程实现,则是通过 listen 和 connect 函数实现 tcp 连接的建立,通过 clo 函数关闭 socket 套接字,实现tcp连接的断开。

2. socket 编程

下面分别介绍客户端和服务端的常用函数和具体实现过程。

2.1 服务端

服务端的实现过程如下图所示。

下面给出实现基于tcp的服务端的常用函数。

1.首先需要对 winsock 套接字库进行初始化,调用 wsastartup 函数。
下面给出 wsastartup 函数调用的基本格式,一般只需调用即可,无需了解参数含义。

#include <winsock2.h>int main(int argc, char* argv[]){wsadata wsadata;if(wsastartup(makeword(2, 2), &wsadata)!=0)errorhandling("wsastartup() error!"); return 0;}

成功时返回 0 ,失败返回非零的错误代码值

2.创建 socket 套接字

socket socket(int af, int type, int protocol);

成功时返回套接字句柄,失败返回 invalid_socket

3.调用 bind 函数,为套接字分配 ip 地址和端口号

int bind(socket s, const struct sockaddr * name, int namelen);

成功时返回 0,失败返回 socket_error

4.调用 listen 函数,监听客户端连接

int listen(socket s, int backlog);

成功时返回 0 ,失败返回 socket_error

5.调用 accept 函数,允许客户端连接

socket accept(socket s, struct sockaddr * addr, int * addrlen);

成功时返回套接字句柄,失败返回 invalid_socket

6.调用 nd 函数, 给连接的客户端发送数据

int nd(socket s, const char * buf, int len, int flags):

成功时返回传输字节数,失败返回 socket_error

7.调用 recv 函数,接收连接的客户端发来的数据

int recv(socket s, const char * buf, int len, int flags);

成功时返回接收字节数,失败返回 socket_error

8.调用 clo 函数,关闭套接字。

int closocket(socket s);

成功时返回 0 ,失败时返回 socket_error

9.注销 winsock 相关库

int wsacleanup(void);

成功时返回 0 ,失败时返回 socket_error

2.2 客户端

客户端的实现过程如下图所示。

下面给出实现基于tcp的客户端的常用函数。

1.创建 socket 套接字

socket socket(int af, int type, int protocol);

成功时返回套接字句柄,失败返回 invalid_socket

2.调用connect函数,发起连接请求

int connect(socket s, const struct sockaddr * name, int namelen);

成功时返回 0,失败返回 socket_error

3.调用 nd 函数, 给连接的服务端发送数据

int nd(socket s, const char * buf, int len, int flags):

成功时返回传输字节数,失败返回 socket_error

4.调用 recv 函数,接收连接的服务端发来的数据

int recv(socket s, const char * buf, int len, int flags);

成功时返回接收字节数,失败返回 socket_error

5.调用 clo 函数,断开连接。

int closocket(socket s);

成功时返回 0 ,失败时返回 socket_error

3. demo展示

3.1 服务端源代码

回声服务端的c++代码

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#pragma comment(lib, "ws2_32.lib")#define buf_size 1024void errorhandling(char *message);int main(int argc, char *argv[]){  wsadata wsadata;  socket hrvsock, hclntsock; 后来的我们豆瓣 char message[buf_size];  int strlen, i;  sockaddr_in rvadr, clntadr;  int clntadrsize;  if (argc != 2)  {    printf("usage : %s <port>\n", argv[0]);    exit(1);  }  if (wsastartup(makeword(2, 2), &wsadata) != 0)    errorhandling("wsastartup() error!");  hrvsock = socket(pf_inet, sock_stream, 0);  if (hrvsock == invalid_socket)    errorhandling("socket() error");  memt(&rvadr, 0, sizeof(rvadr));  rvadr.sin_family = af_inet;  /*rvadr.sin_addr.s_addr = htonl(inaddr_any);*/  rvadr.sin_addr.s_addr = inet_addr("127.0.0.1");  rvadr.sin_port = htons(atoi(argv[1]));  if (bind(hrvsock, (sockaddr *)&rvadr, sizeof(rvadr)) == socket_error)    errorhandling("bind() error");  if (listen(hrvsock, 5) == socket_error)    errorhandling("listen() error");  clntadrsize = sizeof(clntadr);  for (i = 0; i < 5; i++)  {    hclntsock = accept(hrvsock, (sockaddr *)&clntadr, &clntadrsize);    if (hclntsock == -1)      errorhandling("accept() error");    el      printf("connected client %d \n", i + 1);    while ((strlen = recv(hclntsock, message, buf_size, 0)) != 0)      nd(hclntsock, message, strlen, 0);    closocket(hclntsock);  }  closocket(hrvsock);  printf("game over");  wsacleanup();  return 0;}void errorhandling(char *message){  fputs(message, stderr);  fputc('\n', stderr);  exit(1);}

注意:运行服务端代码时,须加入命令行参数(端口号)。如代码所示, ip 地址已经绑定 127.0.0.1。配置 tasks.json 如下所示。

{  "version": "2.0.0",  "ta苏州狮子林介绍sks": [    {      "type": "shell",      "label": "c/c++: g++.exe build active file",      "command": "e:\\mingw64\\bin\\g++.exe",      "args": [        "-g",        "${file}",        "-lws2_32",        "-o",        "${filedirname}\${filebanamenoextension}.exe"      ],      "options": {        "cwd":最后学历 "${workspacefolder}"      }, 写母亲的诗     "problemmatcher": ["$gcc"],      "group": {        "kind": "build",        "isdefault": true      }    }  ]}

配置信息 launch.json 如下 。

{  // u intellin to learn about possible attributes.  // hover to view descriptions of existing attributes.  // for more information, visit: /d/file/titlepic/debugging#_launch-configurations  "version": "0.2.0",  "configurations": [    {      "name": "(gdb) 启动",      "type": "cppdbg",      "request": "launch",      "program": "${filedirname}/${filebanamenoextension}.exe",      "args": ["9190"],      "stopatentry": fal,      "cwd": "${workspacefolder}",      "environment": [],      "externalconsole": fal,      "mimode": "gdb",      "midebuggerpath": "e:\\mingw64\\bin\\gdb.exe",      "tupcommands": [        {          "description": "为 gdb 启用整齐打印",          "text": "-enable-pretty-printing",          "ignorefailures": true        }      ]    }  ]}

3.2 客户端源代码

回声客户端的c++代码

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#define buf_size 1024void errorhandling(char *message);int main(int argc, char *argv[]){  wsadata wsadata;  socket hsocket;  char message[buf_size];  int strlen;  sockaddr_in rvadr;  if (argc != 3)  {    printf("usage : %s <ip> <port>\n", argv[0]);    exit(1);  }  if (wsastartup(makeword(2, 2), &wsadata) != 0)    errorhandling("wsastartup() error!");  hsocket = socket(pf_inet, sock_stream, 0);  if (hsocket == invalid_socket)    errorhandling("socket() error");  printf("%s\n", argv[0]);  printf("%s\n", argv[1]);  printf("%s\n", argv[2]);  memt(&rvadr, 0, sizeof(rvadr));  rvadr.sin_family = af_inet;  rvadr.sin_addr.s_addr = inet_addr(argv[1]);  rvadr.sin_port = htons(atoi(argv[2]));  if (connect(hsocket, (sockaddr *)&rvadr, sizeof(rvadr)) == socket_error)    errorhandling("connect() error!");  el    puts("connected...........");  while (1)  {    fputs("input message(q to quit): ", stdout);    fgets(message, buf_size, stdin);    if (!strcmp(message, "q\n") || !strcmp(message, "q\n"))      break;    nd(hsocket, message, strlen(message适合学生的手机), 0);    strlen = recv(hsocket, message, buf_size - 1, 0);    printf("message from rver: %s", message);  }  closocket(hsocket);  wsacleanup();  return 0;}void errorhandling(char *message){  fputs(message, stderr);  fputc('\n', stderr);  exit(1);}

同样,客户端也需要加入命令行参数 127.0.0.1 9190运行。可以通过修改配置文件生成客户端。
也可以通过cmd或者终端生成客户端。cmd 方式如下:
首先通过 g++ 编译器对 client.cpp 文件进行编译生成 .exe 文件。
之后在终端中,输入 client.exe 127.0.0.1 9190 即可创建客户端。

3.3 运行结果

服务端可以服务 5 个客户端,即 accept 队列长度为 5。
客户端的运行结果如下,前5个客户端均与服务端连接成功,可以收到“回声”。第6次连接时,由于服务端断开连接,所以产生连接错误。

服务端的运行结果如下图所示。服务端可以连接5个客户端,之后服务端将断开连接。并显示 “game over”。

参考链接

深入理解tcp协议与udp协议的原理及区别

vscode官方文档

到此这篇关于windows下vscode实现简单回声服务的文章就介绍到这了,更多相关vscode回声服务内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-05 08:20:11,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/4e4dbb7c9315006a9e1b809f940d4581.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Windows下VScode实现简单回声服务的方法.doc

本文 PDF 下载地址:Windows下VScode实现简单回声服务的方法.pdf

上一篇:氯丙烯低沸
下一篇:返回列表
标签:服务端   客户端   函数   回声
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图