select实现简单TCP通信(ubuntu 18.04)
一、服务器程序(server.c)
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/select.h>
- #include <netinet/in.h>
- #include <strings.h>
- #define SERV_PORT 9999
- #define MAXLINE 4096
- #define SA struct sockaddr
- int max(int, int);
- void proSession(FILE*, int, const struct sockaddr*);
- ssize_t writen(int, const void*, size_t);
- char *sock_ntop(const struct sockaddr*, socklen_t);
- int main(int argc, char *argv[]) {
- int listenfd, connfd;
- pid_t childpid;
- socklen_t clilen;
- struct sockaddr_in servaddr;
- struct sockaddr_in cliaddr;
- listenfd = socket(AF_INET, SOCK_STREAM, );
- bzero(&servaddr, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- servaddr.sin_port = htons(SERV_PORT);
- bind(listenfd, (SA *)&servaddr, sizeof(servaddr)); /* 将套接字和套接字地址结构绑定 */
- listen(listenfd, ); /* 将套接字转换为监听套接字 */
- clilen = sizeof(cliaddr);
- if ( (connfd = accept(listenfd, (SA *)&cliaddr, &clilen)) > ) {
- proSession(stdin, connfd, (SA *)&cliaddr); /* 处理会话 */
- }
- exit(0);
- }
- void proSession(FILE *fp, int sockfd, const struct sockaddr *addr) {
- int maxfdp1, stdineof;
- fd_set rset;
- char buf[MAXLINE];
- int n;
- stdineof = ;
- FD_ZERO(&rset);
- for ( ; ; ) {
- if (stdineof == ) {
- FD_SET(fileno(fp), &rset);
- }
- FD_SET(sockfd, &rset);
- maxfdp1 = max(fileno(fp), sockfd) + ;
- select(maxfdp1, &rset, NULL, NULL, NULL);
- if (FD_ISSET(sockfd, &rset)) { /* 套接字描述符就绪 */
- if ( (n = read(sockfd, buf, MAXLINE)) == ) {
- if (stdineof == ) {
- return;
- } else {
- exit(0);
- }
- }
- printf("%s\n", sock_ntop(addr, sizeof(addr)));
- write(fileno(stdout), buf, n);
- printf("\n");
- }
- if (FD_ISSET(fileno(fp), &rset)) { /* 输入描述符就绪 */
- if ( (n = read(fileno(fp), buf, MAXLINE)) == ) {
- stdineof = ;
- shutdown(sockfd, SHUT_WR); /* 发送 FIN */
- FD_CLR(fileno(fp), &rset);
- continue;
- }
- writen(sockfd, buf, n);
- }
- }
- }
- int max(int numberone, int numbertwo) {
- return ( (numberone >= numbertwo)?numberone:numbertwo);
- }
二、客户端程序(client.c)
- #include <stdio.h>
- #include <stdlib.h>
- #include <strings.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- #define SA struct sockaddr
- #define SERV_PORT 9999
- #define MAXLINE 4096
- int max(int, int);
- void proSession(FILE*, int, const struct sockaddr*);
- ssize_t writen(int, const void*, size_t);
- char *sock_ntop(const struct sockaddr*, socklen_t);
- int main(int argc, char *argv[]) {
- pid_t childpid;
- int sockfd;
- struct sockaddr_in servaddr;
- if (argc != ) {
- printf("usage: %s <IPaddress>\n", argv[]);
- exit(-1);
- }
- sockfd = socket(AF_INET, SOCK_STREAM, );
- bzero(&servaddr, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(SERV_PORT);
- inet_pton(AF_INET, argv[], &servaddr.sin_addr);
- if (connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) == ) {
- proSession(stdin, sockfd, (SA *)&servaddr); /* 处理会话 */
- }
- exit(0);
- }
- void proSession(FILE *fp, int sockfd, const struct sockaddr* addr) {
- int maxfdp1, stdineof;
- fd_set rset;
- char buf[MAXLINE];
- int n;
- stdineof = ;
- FD_ZERO(&rset);
- for ( ; ; ) {
- if (stdineof == ) {
- FD_SET(fileno(fp), &rset);
- }
- FD_SET(sockfd, &rset);
- maxfdp1 = max(fileno(fp), sockfd) + ;
- select(maxfdp1, &rset, NULL, NULL, NULL);
- if (FD_ISSET(sockfd, &rset)) { /* 套接字描述符就绪 */
- if ( (n = read(sockfd, buf, MAXLINE)) == ) {
- if (stdineof == ) {
- return;
- } else {
- exit(0);
- }
- }
- printf("%s\n", sock_ntop(addr, sizeof(addr)));
- write(fileno(stdout), buf, n);
- printf("\n");
- }
- if (FD_ISSET(fileno(fp), &rset)) { /* 输入描述符就绪 */
- if ( (n = read(fileno(fp), buf, MAXLINE)) == ) {
- stdineof = ;
- shutdown(sockfd, SHUT_WR); /* 发送 FIN */
- FD_CLR(fileno(fp), &rset);
- continue;
- }
- writen(sockfd, buf, n);
- }
- }
- }
- int max(int numberone, int numbertwo) {
- return ( (numberone >= numbertwo)?numberone:numbertwo);
- }
三、服务器程序或客户端程序用到的程序
(1)sock_ntop.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <netinet/in.h>
- #include <sys/un.h>
- #include <arpa/inet.h>
- #include <sys/socket.h>
- char *sock_ntop(const struct sockaddr *sa, socklen_t salen) {
- char portstr[];
- static char str[];
- switch (sa->sa_family) {
- case AF_INET: {
- struct sockaddr_in *sin = (struct sockaddr_in *) sa;
- if (inet_ntop(AF_INET, &sin->sin_addr, str,
- sizeof(str)) == NULL) {
- return(NULL);
- }
- if (ntohs(sin->sin_port) != ) {
- snprintf(portstr, sizeof(portstr), ":%d",
- ntohs(sin->sin_port));
- strcat(str, portstr);
- }
- return(str);
- }
- case AF_INET6: {
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
- str[] = '[';
- if (inet_ntop(AF_INET6, &sin6->sin6_addr, str + ,
- sizeof(str) - ) == NULL) {
- return(NULL);
- }
- if (ntohs(sin6->sin6_port) != ) {
- snprintf(portstr, sizeof(portstr), "]:%d",
- ntohs(sin6->sin6_port));
- strcat(str, portstr);
- return(str);
- }
- return (str + );
- }
- case AF_UNIX: {
- struct sockaddr_un *unp = (struct sockaddr_un *) sa;
- if (unp->sun_path[] == ) {
- strcpy(str, "(no pathname bound)");
- } else {
- snprintf(str, sizeof(str), "%s", unp->sun_path);
- }
- return(str);
- }
- default: {
- snprintf(str, sizeof(str), "sock_ntop: unknown AF_xxx: %d, len %d",
- sa->sa_family, salen);
- return(str);
- }
- }
- return (NULL);
- }
(2)writen.c
- #include <unistd.h>
- #include <errno.h>
- ssize_t writen(int fd, const void *vptr, size_t n) {
- size_t nleft;
- ssize_t nwriten;
- const char *ptr;
- ptr = vptr;
- nleft = n;
- while (nleft > ) {
- if ( (nwriten = write(fd, ptr, nleft)) <= ) {
- if (nwriten < && errno) {
- nwriten = ; /* call write() again */
- } else {
- return (-); /* error */
- }
- }
- nleft -= nwriten;
- ptr += nwriten;
- }
- return (n - nwriten);
- }
四、Makefile文件
(1)服务器
- target=server
- cc=gcc
- $(target):writen.o server.o sock_ntop.o
- $(cc) sock_ntop.o writen.o server.o -o $(target)
- sock_ntop.o:sock_ntop.c
- $(cc) -c sock_ntop.c -o sock_ntop.o
- writen.o:writen.c
- $(cc) -c writen.c -o writen.o
- server.o:server.c
- $(cc) -c server.c -o server.o
- clean:
- rm -rf *.o $(target)
(2)客户端
- target=client
- cc=gcc
- $(target):writen.o client.o sock_ntop.o
- $(cc) writen.o client.o sock_ntop.o -o $(target)
- writen.o:writen.c
- $(cc) -c writen.c -o writen.o
- server.o:client.c
- $(cc) -c client.c -o client.o
- sock_ntop.o:sock_ntop.c
- $(cc) -c sock_ntop.c -o sock_ntop.o
- clean:
- rm -rf *.o $(target)
- ~
select实现简单TCP通信(ubuntu 18.04)的更多相关文章
- Ubuntu 18.04及Snap体验——让Linux入门更简单(转))
https://www.linuxidc.com/Linux/2018-06/152993.htm 初次听说过Linux的时候,是大一计算机课时候老师介绍说除了Windows还有Linux.Unix操 ...
- Ubuntu 18.04 LTS 常用软件安装杂记
之前个人笔记本装的是 Linux Mint,用了一段时间但是体验不佳,所以打算换成 Ubuntu .作为一个 Linux 小白,当时配置一些软件环境费了不少时间.这次打算简单记录下,和大家分享一下我的 ...
- 基于Ubuntu 18.04.5 LTS 部署Ceph集群测试及Ceph RDB的使用。
1.ceph简介 Ceph在一个统一的系统中独特地提供对象.块和文件存储 1.1 ceph官网架构图 1.2 架构解释 CEPH 对象存储 CEPH 块设备 CEPH 文件系统 RESTful 接 ...
- Ubuntu 18.04下Couldn't connect to Docker daemon at http+docker://localunixsocket解决办法
一台服务器系统为:Ubuntu 18.04 LTS,上面建了git裸仓库,用于开发吧代码push到这里.同时WEB测试环境通过docker也部署在这台.通过git钩子post-receive,当有新代 ...
- Debian 9 / Debian 10 / Ubuntu 18.04 / Ubuntu 18.10快速开启BBR加速 或 关闭BBR加速
如果使用的是Debian 9.Debian 10.Ubuntu 18.04.Ubuntu 18.10等内核高于4.9版本的系统,均可以使用此方法开启BBR加速,若你使用了Ubuntu 19.04的系统 ...
- 如何在Ubuntu 18.04上安装Apache Web服务器
一. apt库安装 1.在终端输入更新检查命令,sudo apt-get update 2. 在更新完成后(如果不想检查更新,也可直接输入此步)输入:sudo apt-get install apac ...
- Ubuntu 18.04.1 LTS + kolla-ansible 部署 openstack Rocky all-in-one 环境
1. kolla 项目介绍 简介 kolla 的使命是为 openstack 云平台提供生产级别的.开箱即用的自动化部署能力. kolla 要实现 openetack 部署分为两步,第一步是制作 do ...
- 在Ubuntu 18.04系统上安装Systemback的方法(抄)
在Ubuntu 18.04系统上安装Systemback的方法 2018-12-26 21:39:05作者:林莉稿源:云网牛站 本文介绍如何在Ubuntu 18.04或者Ubuntu 18.10系统上 ...
- Ubuntu 18.04 系统配置 NPM环境和mysql数据库问题解决
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效. 今天我就为大家 使用 Ubun ...
随机推荐
- base64加密图片处理
场景:下载html中内嵌的base64加密图片 举个例子,博客园的插入图片有两种方式,一是引用图片链接,二是直接粘贴2进制图片文件.以第二种方式的图片则是以base64加密的方式内嵌在html页面中. ...
- 20165223 结对编程之四则运算week1-阶段性总结
目录 一.结对对象 二.需求分析 三.设计思路 四.功能截图 五.结对感受 一.结对对象 担任角色 驾驶员(Driver):20165223 蔡霓(是控制键盘输入的人) 领航员(Navigator): ...
- Cookie知识点总结
Cookie机制是采用客户端保持Http状态信息的方案. Cookie是在浏览器访问web服务器的某个资源的时候,由web服务器在http响应消息头中附带给浏览器的一个小文本文件. 一旦web服务器保 ...
- 由AC自动机引发的灵感
一,WA自动机 #include <cstdio> using namespace std; int main() { printf("☺"); ; } 二,TLE自动 ...
- A1072. Gas Station
A gas station has to be built at such a location that the minimum distance between the station and a ...
- 收集JavaScript中常用的方法函数
本文中,收集了一些比较常用的Javascript函数,希望对学习JS的朋友们有所帮助. 1. 字符串长度截取 function cutstr(str, len) { var temp, icount ...
- canvas简易画板
代码展示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- iostat 磁盘io分析工具
一:简介 iostat(I/O statistics)输入输出缩写,用来动态监视系统的磁盘操作活动.它能监视磁盘的活动统计情况,同时也能监视CPU的活动情况.缺点是,iostat不能对某一个具体的进程 ...
- 常用的一些cmd命令
常用的一些cmd命令总结 ----------- 1.ping主机名字,类似于ping机子的IP地址 2.查看当前用户的dos命令 3.查看机器名 调出计算器命令:calc 调出远程桌面的命令:mst ...
- golang 热升级
需求场景 干净利落地升级正在运行的agent程序.适用于Devops团队. 目标: 不关闭现有连接:例如我们不希望关掉已部署的运行中的程序.但又想不受限制地随时升级服务. 新的进程要能够启动并替换掉旧 ...