并发服务器的思想是每一个客户的请求并不由服务器直接处理,而是由服务器创建一个子进程来处理

1. 服务器端

#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[];
int *parg = (int *)arg;
int new_fd = *parg; printf("new_fd = %d\n", new_fd); while((size=read(new_fd, recv_buf, )) > )
{
if(recv_buf[]=='@')
break;
printf("Message from client(%d): %s\n",size,recv_buf);
for(j = ; j < size; j++)
recv_buf[j] = toupper(recv_buf[j]);
write(new_fd, recv_buf, size);
} close(new_fd); return ;
} 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[];
int len;
int port;
pthread_t tid; struct sockaddr_in clt_addr;
struct sockaddr_in srv_addr; //服务器端运行时要给出端口信息,该端口为监听端口
if(argc != )
{
printf("Usage:%s port\n", argv[]);
return ;
} //获得输入的端口
port = atoi(argv[]); //创建套接字用于服务器的监听
listen_fd = socket(PF_INET, SOCK_STREAM, );
if(listen_fd < )
{
perror("cannot create listening socket");
return ;
} //填充关于服务器的套节字信息
memset(&srv_addr, , 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 == -)
{
perror("cannot bind server socket");
close(listen_fd);
return ;
} //监听指定端口,连接5个客户端
ret = listen(listen_fd, );
if(ret == -)
{
perror("cannot listen the client connect request");
close(listen_fd);
return ;
}
//对每个连接来的客户端创建一个线程,单独与其进行通信
//首先调用read函数读取客户端发送来的信息
//将其转换成大写后发送回客户端
//当输入“@”时,程序退出
while()
{
len = sizeof(clt_addr); com_fd = accept(listen_fd, (struct sockaddr *)&clt_addr, &len);
if(com_fd < )
{
if(errno == EINTR)
{
continue;
}
else
{
perror("cannot accept client connect request");
close(listen_fd); return ;
}
} printf("com_fd = %d\n", com_fd);//打印建立连接的客户端产生的套节字
if((pthread_create(&tid, NULL, thr_fn, &com_fd)) == -)
{
perror("pthread_create error");
close(listen_fd);
close(com_fd); return ;
}
} return ;
}

2. 客户端

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

TCP并发服务器简单示例的更多相关文章

  1. UNIX网络编程 第5章 TCP客户/服务器程序示例

    UNIX网络编程 第5章 TCP客户/服务器程序示例

  2. TCP通讯模型简单示例

    1. TCP通讯模型 2. 服务器端 ① 创建socket,用函数socket() ② 绑定IP地址.端口号等信息到socket上,用函数bind() ③ 设置允许的最大连接数,用函数listen() ...

  3. tcp并发服务器(c20w)

    ** 原创文章,请勿转载 ** 并发服务器是一个老生常谈的话题,今天这里也写一个. 1. 目标: 同时在线连接20万(c20w). 开发语言:重要的事情说三遍,GOLANG, GOLANG, GOLA ...

  4. UNIX网络编程---TCP客户/服务器程序示例(五)

    一.概述 客户从标准输入读入一行文本,并写给服务器 服务器从网络输入读入这行文本,并回射给客户 客户从网络输入读入这行回射文本,并显示在标准输出上 二.TCP回射服务器程序:main函数 这里给了函数 ...

  5. 3.网络编程-tcp的服务器简单实现

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2019/1/13 22:03 # @Author : ChenAdong # @ema ...

  6. 【Unix 网络编程】TCP 客户/服务器简单 Socket 程序

    建立一个 TCP 连接时会发生下述情形: 1. 服务器必须准备好接受外来的连接.这通常通过调用 socket.bind 和 listen 这三个函数来完成,我们称之为被动打开. 2. 客户通过调用 c ...

  7. TCP客户/服务器简单Socket程序

    建立一个 TCP 连接时会发生下述情形: 1. 服务器必须准备好接受外来的连接.这通常通过调用 socket.bind 和 listen 这三个函数来完成,我们称之为被动打开. 2. 客户通过调用 c ...

  8. Linux网络编程——tcp并发服务器(poll实现)

    想详细彻底地了解poll或看懂下面的代码请参考<Linux网络编程——I/O复用之poll函数> 代码: #include <string.h> #include <st ...

  9. Linux select TCP并发服务器与客户端编程

    介绍:运行在ubuntu linux系统,需要先打开一个终端运行服务端代码,这时,可以打开多个终端同时运行多个客户端代码(注意客户端数目要小于MAX_FD);在客户端输入数据后回车,可以看见服务器收到 ...

随机推荐

  1. c语言中argc和argv

    main函数的参数,解释如下: argc:命令行总的参数的个数,即argv中元素的格式. *argv[ ]:字符串数组,用来存放指向你的字符串参数的指针数组,每一个元素指向一个参数. argv[0]: ...

  2. 静态页面HTML中标签的优化(转)

    静态页面HTML中标签的优化 (2010-04-03 20:54:06) 标签: 电脑 name 罗马数字 css 表单 杂谈 分类: 网页制作 从网上看了一篇关于静态页面中标签优化的问题,感觉还不错 ...

  3. C++的引用的使用

    1引用的定义 引用时C++对C的一个重要的扩充,引用的作用是给变量起一个别名. 例如: int a; int &b=a;//声明b是a的引用 经过以上的声明,b就成为了a的别名,a和b的地位以 ...

  4. SQL server2008无法收缩日志

    SQL server2008无法收缩日志,错误信息为: 1:由于最小日志空间要求,无法收缩日志文件 2:无法收缩日志文件 2 (XXX_log),因为该文件结尾的逻辑日志文件正在使用 描述: 用的是网 ...

  5. Linux 使用静态库注意事项

    1. 静态库一定要放在生成文件后面 gcc main.c -o main libhello.a 2. 使用静态库时一定要连接所有用到的静态库 gcc main.c -o main liba.a lib ...

  6. C语言-郝斌笔记-003数据类型

    基本类型数据 整数 整型     —— int      --4字节  短整型   —— short int   ——2字节 长整型   —— long int    ——8字节      浮点数[实 ...

  7. GPG入门

    GPG入门   摘自https://www.jianshu.com/p/1257dbf3ed8e   Nitroethane 关注 2016.07.19 17:36* 字数 1003 阅读 6560评 ...

  8. TimerTask

    当TimerTask实例通过schedule方法使用之后,不能通过schedule方法调用第二次,如果重复使用就会抛异常TimerTask is scheduled already. 当你重新想利用这 ...

  9. c++特别要点:多态性与虚函数

    本来是准备在工厂模式中顺便整理.但粗略浏览了,内容还是很多,需要单独开一篇. 一.什么是多态性? 多态性可以概括为“一个接口,多种方法”. 多态与非多态的区别在于“成员函数调用地址的早绑定和晚绑定”. ...

  10. WPF之MVVM模式(1)

    MVVM模式 一.MVVM模式概述 MVVM Pattern : Model\View\ViewModel View:视图.UI界面 ViewModel:ViewModel是对Model的封装,通过一 ...