阻塞式I/O实现简单TCP通信
一、技术简介
(1)服务端打开两个端口9999和6666监听外来连接;
(2)服务端的子进程通过端口9999监听外来消息,通过端口6666发送消息;
(3)客户端的子进程处理外来消息,父进程发送消息
二、服务器程序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/un.h> #define SERV_PORT1 9999
#define SERV_PORT2 6666
#define MAXLINE 4096 #define SA struct sockaddr void send_msg(int);
void listen_msg(int, const struct sockaddr*);
char *sock_ntop(const struct sockaddr*, socklen_t); int main(int argc, char *argv[]) {
int listenfd1, connfd1;
int listenfd2, connfd2;
pid_t childpid;
socklen_t clilen1, clilen2;
struct sockaddr_in servaddr1, servaddr2;
struct sockaddr_in cliaddr1, cliaddr2; listenfd1 = socket(AF_INET, SOCK_STREAM, );
listenfd2 = socket(AF_INET, SOCK_STREAM, ); bzero(&servaddr1, sizeof(servaddr1));
servaddr1.sin_family = AF_INET;
servaddr1.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr1.sin_port = htons(SERV_PORT1); bzero(&servaddr2, sizeof(servaddr2));
servaddr2.sin_family = AF_INET;
servaddr2.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr2.sin_port = htons(SERV_PORT2); bind(listenfd1, (SA *)&servaddr1, sizeof(servaddr1));
bind(listenfd2, (SA *)&servaddr2, sizeof(servaddr2)); listen(listenfd1, );
listen(listenfd2, ); clilen1 = sizeof(cliaddr1);
clilen2 = sizeof(cliaddr2);
connfd1 = accept(listenfd1, (SA *)&cliaddr1, &clilen1);
connfd2 = accept(listenfd2, (SA *)&cliaddr2, &clilen2); if (connfd1 && connfd2) {
if ( (childpid = fork()) == ) {
close(listenfd2);
close(connfd2);
close(listenfd1);
listen_msg(connfd1, (SA *)&cliaddr1);
close(connfd1);
exit();
}
close(listenfd1);
close(connfd1);
close(listenfd2);
send_msg(connfd2);
close(connfd2);
}
exit();
} void listen_msg(int sockfd, const struct sockaddr *addr) {
ssize_t n;
char buf[MAXLINE]; while ( (n = read(sockfd, buf, MAXLINE)) > ) {
printf("[%s]: ", sock_ntop(addr, sizeof(addr)));
fputs(buf, stdout);
bzero(buf, sizeof(buf));
}
} void send_msg(int sockfd) {
char buf[MAXLINE]; while (fgets(buf, MAXLINE, stdin) != NULL) {
write(sockfd, buf, sizeof(buf));
}
} 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);
}
三、客户端程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/un.h> #define SA struct sockaddr
#define SERV_PORT1 9999
#define SERV_PORT2 6666
#define MAXLINE 4096 void send_msg(int);
void listen_msg(int, const struct sockaddr*);
char *sock_ntop(const struct sockaddr*, socklen_t); int main(int argc, char *argv[]) {
pid_t childpid;
int sockfd1,sockfd2;
int connstatus1, connstatus2;
struct sockaddr_in servaddr1, servaddr2; if (argc != ) {
printf("usage: %s <IPaddress>\n", argv[]);
exit();
} sockfd1 = socket(AF_INET, SOCK_STREAM, );
sockfd2 = socket(AF_INET, SOCK_STREAM, ); bzero(&servaddr1, sizeof(servaddr1));
servaddr1.sin_family = AF_INET;
servaddr1.sin_port = htons(SERV_PORT1);
inet_pton(AF_INET, argv[], &servaddr1.sin_addr); bzero(&servaddr2, sizeof(servaddr2));
servaddr2.sin_family = AF_INET;
servaddr2.sin_port = htons(SERV_PORT2);
inet_pton(AF_INET, argv[], &servaddr2.sin_addr); connstatus1 = connect(sockfd1, (SA *)&servaddr1, sizeof(servaddr1));
connstatus2 = connect(sockfd2, (SA *)&servaddr2, sizeof(servaddr2)); if (connstatus1 == && connstatus2 == ) {
if ( (childpid = fork()) == ) {
close(sockfd1);
listen_msg(sockfd2, (SA *)&servaddr2);
close(sockfd2);
exit();
}
close(sockfd2);
send_msg(sockfd1);
close(sockfd1);
} else {
printf("connect failed!\n");
}
exit();
} void listen_msg(int sockfd, const struct sockaddr *addr) {
ssize_t n;
char buf[MAXLINE]; while ( (n = read(sockfd, buf, MAXLINE)) > ) {
printf("[%s]: ", sock_ntop(addr, sizeof(addr)));
fputs(buf, stdout);
bzero(buf, sizeof(buf));
}
} void send_msg(int sockfd) {
char buf[MAXLINE]; while (fgets(buf, MAXLINE, stdin) != NULL) {
write(sockfd, buf, sizeof(buf));
}
} 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);
}
阻塞式I/O实现简单TCP通信的更多相关文章
- python socket和简单tcp通信实现
python 服务端和客户端的简单交互 TCP服务端: 1 创建套接字,绑定套接字到本地IP与端口 s = socket.socket(socket.AF_INET,socket.SOCK_STREA ...
- [C++] socket - 1 [简单TCP通信C\S代码]
服务端: #include<iostream> #include<winsock2.h> #include<stdio.h> #pragma comment(lib ...
- C# 简单Tcp通信demo
Client 代码 private void btnSend_Click(object sender, EventArgs e) { TcpClient tcpClient = new TcpClie ...
- select实现简单TCP通信(ubuntu 18.04)
一.服务器程序(server.c) #include <stdio.h> #include <unistd.h> #include <stdlib.h> #incl ...
- QT 简单 TCP 通信,发送数据到服务器
1.首先 添加头文件 #include <QtNetwork/QTcpSocket> 并且 在 xxx.pro(xxx指工程的名称) 中QT += core gui下面,添加 下面两句句话 ...
- 【Java】同步阻塞式(BIO)TCP通信
TCP BIO 背景 网络编程的基本模型是Clien/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接 ...
- java 网络编程之TCP通信和简单的文件上传功能
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- python 简单搭建非阻塞式单进程,select模式,epoll模式服务
由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 : --> 点击这里 可以看我的上篇文章 <python 简单搭建阻塞式单进程,多进程, ...
- python 简单搭建阻塞式单进程,多进程,多线程服务
由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 : --> 点击这里 我们可以通过这样子的方式去理解apache的工作原理 1 单进程TCP服 ...
随机推荐
- 解决win10“cmd自动弹出一闪而过”问题的方法
1.禁用CMD win+Q gpedit 打开组策略 用户配置--管理模板--系统--阻止访问命令提示符--已启用. 2.启用PowerShell PS:需要使用CMD时可用powershell代替: ...
- 解决mysql配置文件my.cnf添加max_connections不生效
问题描述: 最新为了方便测试,通过mysql官方指定的yum源安装了mysql5.6.40,在向mysql的配置文件my.cnf添加max_connections=3600后,重启mysql后发现不生 ...
- LOJ#2720 你的名字
题意:给定母串s和若干个询问.每个询问是一个串t和两个数l,r,表示求t中有多少个本质不同的子串没有在s[l,r]中出现过. 解:我写的并不是正解......是个毒瘤做法.只在loj上面卡时过了就写l ...
- PHP原生处理select结果集的函数介绍
select: mysql_num_rows($result) 从结果集中获取数据记录的个数 mysql_num_fields($result) 从结果集中获取数据记录列的个数 mysql_fetch ...
- Spring MVC 架构的java web工程如何添加登录过滤器
发布到外网的web工程必须添加登录过滤器来阻挡一些非法的请求,即只有登录的用户才能对web工程进行请求,否则无论请求什么资源都需要调整到登录页面进行登录操作.这时就需要用到过滤器,其实非常简单,只需要 ...
- gitlab 500 服务器错误 重启解决了
查看状态 sudo gitlab-ctl status # 启动Gitlab所有组件 sudo gitlab-ctl start # 停止Gitlab所有组件 sudo gitlab-ctl stop ...
- (01背包 dp)P1049 装箱问题 洛谷
题目描述 有一个箱子容量为VV(正整数,0≤V≤20000),同时有nn个物品(0<n≤30,每个物品有一个体积(正整数). 要求nn个物品中,任取若干个装入箱内,使箱子的剩余空间为最小. 输入 ...
- Java Web 开发必须掌握的三个技术:Token、Cookie、Session
在Web应用中,HTTP请求是无状态的.即:用户第一次发起请求,与服务器建立连接并登录成功后,为了避免每次打开一个页面都需要登录一下,就出现了cookie,Session. Cookie Cookie ...
- 列举一些 MacBook Pro 必需的外设和应用程序推荐
来源:知乎 文章收录于:风云社区SCOEE,提供上千款mac软件下载 基于从事Apps设计或开发者,使用 MacBook Pro,以下罗列一些必需的外设和应用程序推荐. Retina 256GB SS ...
- 2017-12-18python全栈9期第三天第三节之int bool str转换之数字转换成二进制的位数
#!/user/bin/python# -*- coding:utf-8 -*-i= 100print(i.bit_length())