基于 TCP 协议的并发服务器程序

2024-06-14 05:18

本文主要是介绍基于 TCP 协议的并发服务器程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

服务端:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <netdb.h>
#include <pthread.h>//线程执行函数,负责读写
void *thr_fn ( void *arg )
{int size, j;char recv_buf[1024];int *parg = ( int * ) arg;int new_fd = *parg;while ( ( size = read ( new_fd, recv_buf, sizeof ( recv_buf ) ) ) > 0 ) {if ( recv_buf[0] == '@' ) {break;}printf ( "Message from client(%d): %s\n", size, recv_buf );for ( j = 0; j < size; ++j )recv_buf[j] = toupper(recv_buf[j]);write(new_fd,recv_buf,size);}close(new_fd);return 0;
}int main(int argc, char *argv[]){socklen_t clt_addr_len;int listen_fd;int com_fd;int ret;int i;static char recv_buf[1024];int len;int port;pthread_t tid;struct sockaddr_in clt_addr;struct sockaddr_in srv_addr;//服务器端运行时要给出端口信息,该端口为监听端口if(argc != 2){printf("Usage:%s port\n",argv[0]);return -1;}//获得输入的端口port = atoi(argv[1]);//创建套接字用于服务器的监听listen_fd = socket(PF_INET,SOCK_STREAM,0);if(listen_fd < 0){perror("cannot create listening socket");return -1;}//填充关于服务器的套接字信息memset(&srv_addr,0,sizeof(srv_addr));srv_addr.sin_family = AF_INET;srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);srv_addr.sin_port = htons(port);//将服务器和套接字绑定ret = bind(listen_fd,(struct sockaddr *)&srv_addr,sizeof(srv_addr));if(ret == -1){perror("cannot bind server socket");close(listen_fd);return -1;}//监听指定端口ret = listen(listen_fd,5);if(ret == -1){perror("cannot listen the client connect request");close(listen_fd);return -1;}/*对每个连接来的客户端创建一个线程,单独与其进行通信,首先调用 read 函数读取客户端发送来的信息将其转化成大写后发送回客户端当输入"@"时,程序退出*/while(1){len = sizeof(clt_addr);com_fd = accept(listen_fd,(struct sockaddr *)&clt_addr,&len);if(com_fd < 0){if(errno == EINTR)continue;else{perror("cannot accept client connect request");close(listen_fd);return -1;}}printf("com_fd = %d\n",com_fd); //打印建立连接的客户端产生的套接字if((pthread_create(&tid,NULL,thr_fn,&com_fd)) == -1){perror("pthread_create error");close(listen_fd);close(com_fd);return -1;}}return 0;
}

客户端:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <unistd.h>int main(int argc, char**argv){int connect_fd;int ret;char snd_buf[1024];int i;int port;int len;static struct sockaddr_in srv_addr;//客户端运行需要给出具体的连接地址和端口if(argc != 3){printf("Usage: %s server_ip_address port\n",argv[0]);return -1;}//获得输入的端口port = atoi(argv[2]);//创建套接字用于客户端的连接connect_fd = socket(PF_INET,SOCK_STREAM,0);if(connect_fd < 0){perror("cannot create communication socket");return 1;}//填充关于服务器的套接字信息memset(&srv_addr,0,sizeof(srv_addr));srv_addr.sin_family = AF_INET;srv_addr.sin_addr.s_addr = inet_addr(argv[1]);srv_addr.sin_port = htons(port);//连接指定的服务器ret = connect(connect_fd,(struct sockaddr *)&srv_addr,sizeof(srv_addr));if(ret == -1){perror("cannot connect to the server");close(connect_fd);return -1;}memset(snd_buf,0,1024);/*用户输入信息后,程序将输入的信息通过套接字发送给服务器,然后调用read函数从服务器中读取发送来的信息当输入"@"时,程序退出*/while(1){write(STDOUT_FILENO,"input message:", 14);len = read(STDIN_FILENO,snd_buf,1024);if(len > 0)write(connect_fd,snd_buf,len);len = read(connect_fd,snd_buf,len);if(len > 0)printf("Message form server: %s\n",snd_buf);if(snd_buf[0] == '@')break;}close(connect_fd);return 0;
}



这篇关于基于 TCP 协议的并发服务器程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1059482

相关文章

HTTP 与 SpringBoot 参数提交与接收协议方式

《HTTP与SpringBoot参数提交与接收协议方式》HTTP参数提交方式包括URL查询、表单、JSON/XML、路径变量、头部、Cookie、GraphQL、WebSocket和SSE,依据... 目录HTTP 协议支持多种参数提交方式,主要取决于请求方法(Method)和内容类型(Content-Ty

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

Spring Security 前后端分离场景下的会话并发管理

《SpringSecurity前后端分离场景下的会话并发管理》本文介绍了在前后端分离架构下实现SpringSecurity会话并发管理的问题,传统Web开发中只需简单配置sessionManage... 目录背景分析传统 web 开发中的 sessionManagement 入口ConcurrentSess

Java对接MQTT协议的完整实现示例代码

《Java对接MQTT协议的完整实现示例代码》MQTT是一个基于客户端-服务器的消息发布/订阅传输协议,MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛,:本文主要介绍Ja... 目录前言前置依赖1. MQTT配置类代码解析1.1 MQTT客户端工厂1.2 MQTT消息订阅适配器1.

MySQL中处理数据的并发一致性的实现示例

《MySQL中处理数据的并发一致性的实现示例》在MySQL中处理数据的并发一致性是确保多个用户或应用程序同时访问和修改数据库时,不会导致数据冲突、数据丢失或数据不一致,MySQL通过事务和锁机制来管理... 目录一、事务(Transactions)1. 事务控制语句二、锁(Locks)1. 锁类型2. 锁粒

深入解析Java NIO在高并发场景下的性能优化实践指南

《深入解析JavaNIO在高并发场景下的性能优化实践指南》随着互联网业务不断演进,对高并发、低延时网络服务的需求日益增长,本文将深入解析JavaNIO在高并发场景下的性能优化方法,希望对大家有所帮助... 目录简介一、技术背景与应用场景二、核心原理深入分析2.1 Selector多路复用2.2 Buffer

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

Linux之UDP和TCP报头管理方式

《Linux之UDP和TCP报头管理方式》文章系统讲解了传输层协议UDP与TCP的核心区别:UDP无连接、不可靠,适合实时传输(如视频),通过端口号标识应用;TCP有连接、可靠,通过确认应答、序号、窗... 目录一、关于端口号1.1 端口号的理解1.2 端口号范围的划分1.3 认识知名端口号1.4 一个进程

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到