谈谈Tcpserver开启多线程并发处理遇到的问题!

news/2024/9/25 17:14:14/

最近在学习最基础的socket网络编程,在Tcpserver开启多线程并发处理时遇到了一些问题!

说明

linux以及Windows的共享文件夹进行编写的,所以代码中有的部分使用

#ifdef WIN64
...
#else
...
#endif 

进入正题!!!
先来看看代码~

#include <string.h>
#include <stdlib.h>
#include <stdio.h>#ifdef _WIN64
#include<windows.h>
#define socklen_t int
#else
#include <sys/types.h>          
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#define  closesocket close   //因为linux和Windows下不同,所以定义了一个宏
#endif #include <thread>
using namespace std;
class TcpThread //建立一个线程类
{
public:void Main() //入口函数{char buf[1024] = { 0 };for (;;){int recvlen = recv(client, buf, sizeof(buf) - 1, 0);if (recvlen <= 0) break;buf[recvlen] = '\0';//在结尾加\0if (strstr(buf, "quit") != NULL) {char re[] = "quit success\n";send(client, re, strlen(re) + 1, 0);break;}int sendlen = send(client, "ok\n", 4, 0);printf("recv %s\n", buf);}closesocket(client); //关闭delete this;//要确保TcpThread 是new出来的}int client = 0;
};#include<stdio.h>
int main( int argc, char *argv[])
{
#ifdef WIN64WSADATA ws;WSAStartup(MAKEWORD(2, 2), &ws);
#endif // WIN64int sock=socket(AF_INET, SOCK_STREAM, 0);if (sock == -1){printf("create socket failed!\n");return -1;}printf("[%d]", sock);unsigned short port = 8080;if (argc > 1) //如果输入端口,则使用输入的,否则用8080{port = atoi(argv[1]);//传递端口号}sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(port);//小端转大端saddr.sin_addr.s_addr = htonl(0);if (::bind(sock, (sockaddr*)&saddr, sizeof(saddr)) != 0){printf("bind port %d faild!\n", port);return -2;}else {printf("bind port %d success!\n", port);}listen(sock, 10);for (;;){sockaddr_in caddr;socklen_t len = sizeof(caddr);int client = accept(sock, (sockaddr* ) & caddr, &len);if (client <= 0) break;printf("accept client %d\n", client);char *ip = inet_ntoa(caddr.sin_addr);unsigned short cport = ntohs(caddr.sin_port);printf("client ip is %s,port is %d\n", ip, cport);TcpThread *th = new TcpThread(); //new出来th->client = client;//传入创建好的clientthread sth(&TcpThread::Main, th);//启动线程sth.detach();//释放主线程拥有的子线程的资源}closesocket(sock);
//#if WIN64
//	closesocket(sock);
//	closesocket(client);
//#else
//	close(sock);
//	close(sock);
//#endif // WIN64return 0;}

这时候直接在linuxmake main会报错
在这里插入图片描述
这说明我们使用c++11,这里我们需要写一个makefile,接着我们
vim makefile
在里面我们写如下代码:
在这里插入图片描述
然后在make,这里发现成功了,然后./tcpserver尝试创建多个线程, 在主线程发现成功了
在这里插入图片描述
用户开始连接,就报错
在这里插入图片描述
这时候我们就要注意了,是makefile里面缺少 -pthread;
在这里插入图片描述
接着在编译运行,发现成功了!!!
在这里插入图片描述

创建多线程,进行测试,

打开两个端口telnet 192.168.xxx.xxx 8081 连接成功如下:
在这里插入图片描述在这里插入图片描述

分别在两个里面发送消息1,2,收到了回复
在这里插入图片描述

然后主线程收到消息,表示成功了!
在这里插入图片描述

注意:

C++是支持多线程,但是需要注意以下三点:

  1. 必须包含头文件#include
  2. 必须有编译选项-std=c++11
  3. 必须有编译选项-pthread,否则运行出现Enable multithreading to use std::thread: Operation not permitted。同时-lpthread和-pthread一样,但是建议使用-pthread。因为编译选项中指定 -pthread 会附加一个宏定义 -D_REENTRANT,该宏会导致 libc 头文件选择那些thread-safe的实现;链接选项中指定 -pthread 则同 -lpthread 一样,只表示链接 POSIX thread 库。由于 libc 用于适应 thread-safe 的宏定义可能变化,因此在编译和链接时都使用 -pthread 选项而不是传统的 -lpthread 能够保持向后兼容,并提高命令行的一致性。

小白初次学习,希望大佬们多多指教!!!


http://www.ppmy.cn/news/1453949.html

相关文章

问题 A: 实验11_4_初识链表

题目描述 已知一个正整数序列&#xff0c;个数未知&#xff0c;但至少有一个元素&#xff0c;你的任务是建立一个单链表&#xff0c;并使用该链表存储这个正整数序列&#xff0c;然后统计这个序列中元素的最大值与最小值&#xff0c;计算序列全部元素之和。正整数的输入用-1作…

ES数据存储与查询基本原理

Elasticsearch&#xff08;ES&#xff09;简介 Elasticsearch&#xff08;ES&#xff09;是一个分布式、可扩展、近实时的搜索和分析引擎&#xff0c;它基于Lucene&#xff0c;设计用于云计算中&#xff0c;处理大规模文档检索和数据分析任务&#xff0c;常用于实现内部搜索引…

ASP.NET网上书店

摘要 本设计尝试用ASP.NET在网络上架构一个电子书城&#xff0c;以使每一位顾客不用出门在家里就能够通过上网来轻松购书。本文从理论和实践两个角度出发&#xff0c;对一个具有数据挖掘功能电子书城进行设计与实现分析。论文首先较为详尽地介绍了面向对象分析与设计的有关概念…

github.com/gin-contrib/timeout应前置使用

首先&#xff0c;gin的中间件是有执行顺序的&#xff0c;就是按照添加的顺序进行的。之前没在意&#xff0c;我把timeout中间件放在了最后面&#xff0c;导致业务一直不正常&#xff0c;后面debug源码总算看明白了&#xff1a; 源码入口&#xff1a; func(c *gin.Context) {fi…

基于springboot+vue+Mysql的自习室预订系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

【Linux—进程间通信】共享内存的原理、创建及使用

什么是共享内存 共享内存是一种计算机编程中的技术&#xff0c;它允许多个进程访问同一块内存区域&#xff0c;以此作为进程间通信&#xff08;IPC, Inter-Process Communication&#xff09;的一种方式。这种方式相对于管道、套接字等通信手段&#xff0c;具有更高的效率&…

【LeetCode】链表oj专题

前言 经过前面的学习&#xff0c;咋们已经学完了链表相关知识&#xff0c;这时候不妨来几道链表算法题来巩固一下吧&#xff01; 如果有不懂的可翻阅之前文章哦&#xff01; 个人主页&#xff1a;小八哥向前冲~-CSDN博客 数据结构专栏&#xff1a;数据结构【c语言版】_小八哥…

【MySQL】第一次作业

【MySQL】第一次作业 1、在官网下载安装包2、解压安装包&#xff0c;创建一个dev_soft文件夹&#xff0c;解压到里面。3、创建一个数据库db_classes4、创建一行表db_hero5、将四大名著中的常见人物插入这个英雄表 写一篇博客&#xff0c;在window系统安装MySQL将本机的MySQL一定…