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 ...
随机推荐
- Python里的赋值 拷贝 深拷贝
import copy a = [1, 2, 3, 4, ['a', 'b']] #原始对象 b = a #赋值,传对象的引用 c = copy.copy(a) #对象拷贝,浅拷贝 d = copy. ...
- Django(二十)model中的 class Meta
https://www.cnblogs.com/tongchengbin/p/7670927.html class Main(models.Model): img = models.CharField ...
- Django(十六)Form组件扩展
http://www.cnblogs.com/wupeiqi/articles/6144178.html Form组件 - form表单(验证:保留上次内容) - - Ajax(验证:无需上次内容) ...
- quartz和spring集成使用一例子【我】
首先在spring配置文件中增加: <!-- 调度器 --> <bean name="scheduler" lazy-init="false" ...
- 洛谷 P1061 Jam的计数法
传送门 题解: 相关变量解释: int s,t,w; ;//最多输出五组 int maxNum[maxn];//maxNum[i] : i 位置可以达到的最大值 char letter[maxn]; ...
- 转:mysql分页原理和高效率的mysql分页查询语句
(转自:http://www.jb51.net/article/46015.htm) 以前我在mysql中分页都是用的 limit 100000,20这样的方式,我相信你也是吧,但是要提高效率,让分页 ...
- Java 引用数据类型
引用数据类型 * A: 数据类型 * a: java中的数据类型分为:基本类型和引用类型 * B: 引用类型的分类 * a: Java为我们提供好的类,比如说:Scanner,Random等. * C ...
- bzoj4034 线段树+dfs序
https://www.lydsy.com/JudgeOnline/problem.php?id=4034 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 ...
- maven直接饮用jar包的写法
<dependency> <groupId>sample</groupId> <artifactId>com.sample</artifactId ...
- 6-(基础入门篇)学会编译lua固件,固件的合成
http://www.cnblogs.com/yangfengwu/p/9336274.html 基础教程源码链接请在淘宝介绍中下载,由于链接很容易失效,如果失效请联系卖家,谢谢 https://it ...