一、技术简介

 (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通信的更多相关文章

  1. python socket和简单tcp通信实现

    python 服务端和客户端的简单交互 TCP服务端: 1 创建套接字,绑定套接字到本地IP与端口 s = socket.socket(socket.AF_INET,socket.SOCK_STREA ...

  2. [C++] socket - 1 [简单TCP通信C\S代码]

    服务端: #include<iostream> #include<winsock2.h> #include<stdio.h> #pragma comment(lib ...

  3. C# 简单Tcp通信demo

    Client 代码 private void btnSend_Click(object sender, EventArgs e) { TcpClient tcpClient = new TcpClie ...

  4. select实现简单TCP通信(ubuntu 18.04)

    一.服务器程序(server.c) #include <stdio.h> #include <unistd.h> #include <stdlib.h> #incl ...

  5. QT 简单 TCP 通信,发送数据到服务器

    1.首先 添加头文件 #include <QtNetwork/QTcpSocket> 并且 在 xxx.pro(xxx指工程的名称) 中QT += core gui下面,添加 下面两句句话 ...

  6. 【Java】同步阻塞式(BIO)TCP通信

    TCP BIO 背景 网络编程的基本模型是Clien/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接 ...

  7. java 网络编程之TCP通信和简单的文件上传功能

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  8. python 简单搭建非阻塞式单进程,select模式,epoll模式服务

    由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 :  --> 点击这里 可以看我的上篇文章 <python 简单搭建阻塞式单进程,多进程, ...

  9. python 简单搭建阻塞式单进程,多进程,多线程服务

    由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 :  --> 点击这里 我们可以通过这样子的方式去理解apache的工作原理 1 单进程TCP服 ...

随机推荐

  1. IP地址等价类测试用例

    下面是一个比较完善的设计方案,这个方案中,首先把IP地址分成有效可用的IP地址和有效但不可用的IP地址两个等价类:其中有效可用的IP地址中包括IP地址的A,B,C三类地址,有效但不可用的IP地址包括D ...

  2. luogu3759 不勤劳的图书管理员 (树状数组套线段树)

    交换的话,只有它们中间的书会对答案产生影响 树状数组记位置,套线段树记书的编号 它对应的页数和书的个数 然后就是减掉中间那些原来是逆序对的,再把交换以后是逆序对的加上 别忘了考虑这两个自己交换以后是不 ...

  3. Xposed+JustTrustMe+Android

    场景介绍:APP抓包 引出的知识点:ssl-pinning. ssl-pinning: apk在开发时就将服务端证书一块打包到客户端里.这样在HTTPS建立时与服务端返回的证书比对一致性,进而识别出中 ...

  4. pandas中遍历dataframe的每一个元素

    假如有一个需求场景需要遍历一个csv或excel中的每一个元素,判断这个元素是否含有某个关键字 那么可以用python的pandas库来实现. 方法一: pandas的dataframe有一个很好用的 ...

  5. Flask 应用上下文

    应用上下文(application context) 它的字面意思是 应用上下文,但它不是一直存在的,它只是request context 中的一个对 app 的代理(人),所谓local proxy ...

  6. 第二十六篇-单击事件、Toast(提示框信息)

    单击事件有3种方法: 第一种: layout.xml <?xml version="1.0" encoding="utf-8"?> <Line ...

  7. 2019_01_16 sem_init

    sem_init() #include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int value); S ...

  8. Educational Codeforces Round 53 (Rated for Div. 2) A Diverse Substring

    传送门 https://www.cnblogs.com/violet-acmer/p/10163375.html 题意: 给出串是多态的定义“长度为 n 的串 s ,当串 s 中所有字母出现的次数严格 ...

  9. php如何判断数组是一维还是多维

    php>4.2 int count ( mixed $var [, int $mode ] )  --  计算数组中的单元数目或对象中的属性个数  如果可选的 mode 参数设为 COUNT_R ...

  10. 非root用户ssh 执行 sudo远程机器免密钥

    非root用户ssh 执行 sudo远程机器免密钥 # 1.登陆192.168.1.10 ssh-keygen -t rsa # 一路回车 # 将公钥添加到认证文件中 cat ~/.ssh/id_rs ...