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

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++——override

    override关键字作用: 如果派生类在虚函数声明时使用了override描述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译.举例子说明 struct Base { virtual ...

  2. Python中for else注意事项

    假设有如下代码: for i in range(10): if i == 5: print 'found it! i = %s' % i else: print 'not found it ...' ...

  3. Tensorflow手写数字识别(交叉熵)练习

    # coding: utf-8import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_data #pr ...

  4. 业务逻辑:shiro框架的功能实现

    思路:分别在web.xml配置过滤器以及在applicationContext.xml去配置 实现步骤:1.在pom.xml里引入shiro的坐标 2.在web.xml里配置shiro过滤器 3.在a ...

  5. PDF的一些工具

    PdfStreamDumper Pdftk 这里有一个链接,列出了很多pdf免费工具 https://en.wikipedia.org/wiki/Category:Free_PDF_software ...

  6. java8的十大新特性

    推荐学习的博客: http://blog.csdn.net/renfufei/article/details/24600507/-------讲解的非常通俗易懂 http://blog.csdn.ne ...

  7. TCP/IP的三次握手和四次放手

    一开始个人对于三次握手和四次挥手这个东西还是有时候会忘记,可能理解的不是非常深刻,所以今天就自己动手来记录一下这个知识点,方便以后查看.总结完之后发现总结的还是可以的哈哈. 三次握手建立连接 第一次: ...

  8. JDBC 配置环境

    一.配置JDBC环境:先下载驱动jar包 1.配置classpath环境变量  如(E:\jdbc\mysql-connector-java-5.1.7-bin.jar) 2.数据库URL: 2.1 ...

  9. Mac下的UI自动化测试 (三)

    使用sikuli进行UI自动化测试固然是方便很多,不用一切都使用AppleScript那烦人的语法,只要界面的UI没有变化,结构的变化不会影响到基于sikuli的自动化,但是基于AppleScript ...

  10. Dojo Style Guide

    Contents: General Quick Reference Naming Conventions Specific Naming Conventions Files Variables Lay ...