然后基本的socket编程,用TCP做两个进程互相发消息。C端主动发hello,S端收到后回world。

 #include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h> #define MAXLINE 80
#define SERV_PORT 8000 int main()
{
char buf[MAXLINE];
int listenfd = ; listenfd = socket(AF_INET, SOCK_STREAM, ); struct sockaddr_in servaddr = {};
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, ); printf("Accepting connections ...\n");
while() {
struct sockaddr_in cliaddr = {};
socklen_t cliaddr_len = sizeof(cliaddr);
int connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); char str[INET_ADDRSTRLEN];
printf("connect from %s at PORT %d\n",
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
while() {
int count = read(connfd, buf, MAXLINE);
if(count == )
break; if(!strcmp(buf, "Hello")) {
printf("client send %s\n", buf);
write(connfd, "World", );
}
}
close(connfd);
printf("closed from %s at PORT %d\n",
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
}
return ;
}

server.c

c端

 #include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h> #define MAXLINE 80
#define SERV_PORT 8000
#define MESSAGE "Hello" int main(int argc, char *argv[])
{
char buf[MAXLINE]; int sockfd = socket(AF_INET, SOCK_STREAM, ); struct sockaddr_in servaddr = {};
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT); if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != )
{
printf("connected failed");
return ;
} write(sockfd, MESSAGE, sizeof(MESSAGE));
int count = read(sockfd, buf, MAXLINE); printf("Response from server: %s\n", buf); close(sockfd);
return ;
}

client

然后把S端用EPOLL做成异步处理,可以同时给好几个C端回复。

 #include <iostream>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h> using namespace std; #define MAXLINE 5
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 8000
#define INFTIM 1000 int main(void)
{
int i, maxi, listenfd, connfd, sockfd, epfd, nfds;
ssize_t n;
char line[MAXLINE];
char buf[];
socklen_t clilen; struct epoll_event ev, events[];
epfd = epoll_create();
struct sockaddr_in clientaddr;
struct sockaddr_in serveraddr;
listenfd = socket(AF_INET, SOCK_STREAM, ); ev.data.fd = listenfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev); bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERV_PORT);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(listenfd, (sockaddr *)&serveraddr, sizeof(serveraddr));
listen(listenfd, LISTENQ); for( ; ; ) {
nfds = epoll_wait(epfd, events, , ); for(i=;i<nfds;i++) {
if(events[i].data.fd == listenfd) {
clilen = sizeof(clientaddr);
connfd = accept(listenfd, (sockaddr *)&clientaddr, &clilen);
ev.data.fd = connfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
} else if(events[i].events & EPOLLIN) {
if((sockfd = events[i].data.fd) < ) {
continue;
}
if((n = read(sockfd, line, MAXLINE)) < ) {
if(errno == ECONNRESET) {
close(sockfd);
events[i].data.fd = -;
} else {
std::cout<<"readline error"<<std::endl;
}
} else if(n == ) {
close(sockfd);
events[i].data.fd = -;
}
ev.data.fd = sockfd;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
} else if(events[i].events & EPOLLOUT) {
sockfd = events[i].data.fd;
if(!strcmp(line, "Hello")) {
strcpy(buf, "World");
write(sockfd, buf, );
}
ev.data.fd = sockfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
}
}
}
}

epoll server

c端

 #include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h> #define MAXLINE 80
#define SERV_PORT 8000
#define MESSAGE "Hello" int main(int argc, char *argv[])
{
char buf[MAXLINE]; int sockfd = socket(AF_INET, SOCK_STREAM, ); struct sockaddr_in servaddr = {};
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.1.63", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT); if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != ) {
printf("connected failed");
return ;
} for( ; ;) {
write(sockfd, MESSAGE, sizeof(MESSAGE));
int count = read(sockfd, buf, MAXLINE); printf("Response from server: %s\n", buf);
sleep();
}
close(sockfd);
return ;
}

epoll client

4,然后把S做成多进程,任何一个进程收到任何一个C端的消息后,广播给其他进程,然后所有进程打印如下信息:“几号”进程收到“几号”客户端的“啥啥”消息(由“几号”进程转发)。不是转发的,括号内省略。“”内的替换为正确值。

S端:

 #ifndef _3PROCESS_FD_H_
#define _3PROCESS_FD_H_ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream> using namespace std; #include <sys/socket.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <errno.h>
#include "3process_fun.h" typedef struct {
int index;
int chanel[];
}process_t; #define MAXPROCESS 3
#define MAXLINE 100 #define SERV_PORT 9876 #endif

server.h

 #include "3process_fd.h"

 void setnonblocking(int sock)
{
int opts;
opts = fcntl(sock, F_GETFL);
if(opts < ) {
cout<<"fcntl error"<<endl;
exit();
} opts = opts | O_NONBLOCK;
if(fcntl(sock, F_SETFL, opts) < ) {
cout<<"set nonblock error"<<endl;
exit();
}
} void child_process(int index, process_t *processes)
{
cout<<"child "<<index<<" pid: "<<getpid()<<endl;
struct epoll_event ev, events[];
int epfd, nfds, sockfd, listenfd, connfd;
int i, n;
char buf[MAXLINE], line[MAXLINE];
struct sockaddr_in servaddr;
struct sockaddr_in clientaddr;
socklen_t clilen = sizeof(struct sockaddr_in); /* socket bind and listen */
listenfd = socket(AF_INET, SOCK_STREAM, );
setnonblocking(listenfd);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, ); /* create epoll */
epfd = epoll_create();
ev.data.fd = (processes+index)->chanel[];
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, (processes+index)->chanel[], &ev); ev.data.fd = listenfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev); for( ; ;) {
nfds = epoll_wait(epfd, events, , );
for(i=;i<nfds;i++) {
if(events[i].data.fd == listenfd) {
connfd = accept(listenfd, (sockaddr *)&clientaddr, &clilen);
if(connfd < ) {
cout<<"[child"<<index<<"] accept error"<<endl;
exit();
}
setnonblocking(connfd);
char *str = inet_ntoa(clientaddr.sin_addr);
cout<<"[child"<<index<<"] connect from "<<str<<endl;
ev.data.fd = connfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
} else if(events[i].data.fd == (processes+index)->chanel[]) {
read((processes+index)->chanel[], buf, sizeof(buf));
cout<<"child "<<index<<" recv: "<<buf<<endl;
} else if(events[i].events & EPOLLIN) {
if((sockfd = events[i].data.fd) < ) {
ev.data.fd = sockfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);
continue;
}
if((n = read(sockfd, line, MAXLINE)) < ) {
if(errno == ECONNRESET) {
close(sockfd);
events[i].data.fd = -;
ev.data.fd = sockfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);
} else {
cout<<"readline error"<<endl;
}
} else if(n == ) {
close(sockfd);
events[i].data.fd = -;
ev.data.fd = sockfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);
cout<<"[child"<<index<<"] close socket?"<<endl;
continue;
}
cout<<"[child"<<index<<"] here is a EPOLLIN event."<<endl;
ev.data.fd = sockfd;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
} else if(events[i].events & EPOLLOUT) {
if((sockfd = events[i].data.fd) < ) {
ev.data.fd = sockfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev);
continue;
}
if(!strcmp(line, "Hello")) {
strcpy(buf, "World");
write(sockfd, buf, strlen(buf));
}
cout<<"[child"<<index<<"] here is a EPOLLOUT event."<<endl;
ev.data.fd = sockfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
}
}
} exit();
} int main(int argc, char *argv[])
{
cout<<"current pid: "<<getpid()<<endl;
process_t *pprocess = (process_t *)malloc(sizeof(process_t)*MAXPROCESS);
int i;
int pid[MAXPROCESS]; for(i=;i<MAXPROCESS;i++) {
(pprocess+i)->index = i;
if(socketpair(AF_UNIX, SOCK_STREAM, , (pprocess+i)->chanel) == -) {
cout<<"failed to create domain socket by socketpair"<<endl;
exit();
}
} for(i=;i<MAXPROCESS;i++) {
pid[i] = fork();
switch(pid[i]) {
case -:
cout<<"fork error"<<endl;
exit(-);
case :
child_process(i, pprocess);
exit();
defualt:
cout<<"default?"<<endl;
break;
}
} for(i=;i<MAXPROCESS;i++) {
write((pprocess+i)->chanel[], "Hello child", strlen("Hello child"));
} for(;;) {
pause();
}
}

server.cpp

C端:

 #include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h> #define MAXLINE 80
#define SERV_PORT 9876
#define MESSAGE "Hello" int main(int argc, char *argv[])
{
char buf[MAXLINE]; int sockfd = socket(AF_INET, SOCK_STREAM, ); struct sockaddr_in servaddr = {};
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.1.63", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT); if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != )
{
printf("connected failed:%d,%s",errno, strerror(errno));
return ;
}
while()
{
write(sockfd, MESSAGE, sizeof(MESSAGE));
// int count = read(sockfd, buf, MAXLINE); // printf("Response from server: %s\n", buf);
sleep();
} close(sockfd);
return ;
}

client.c

TCP练习的更多相关文章

  1. Tcp/ip 报文解析

    在编写网络程序时,常使用TCP协议.那么一个tcp包到底由哪些东西构成的呢?其实一个TCP包,首先需要通过IP协议承载,而IP报文,又需要通过以太网传送.下面我们来看看几种协议头的构成 一 .Ethe ...

  2. C#高性能TCP服务的多种实现方式

    哎~~ 想想大部分园友应该对 "高性能" 字样更感兴趣,为了吸引眼球所以标题中一定要突出,其实我更喜欢的标题是<猴赛雷,C#编写TCP服务的花样姿势!>. 本篇文章的主 ...

  3. Android实现TCP断点上传,后台C#服务实现接收

    终端实现大文件上传一直都是比较难的技术,其中涉及到后端与前端的交互,稳定性和流量大小,而且实现原理每个人都有自己的想法,后端主流用的比较多的是Http来实现,因为大多实现过断点下载.但稳定性不能保证, ...

  4. 漫谈TCP

    不得不承认,tcp是一个非常复杂的协议.它包含了RFC793及之后的一些协议.能把tcp的所有方面面面具到地说清楚,本身就是个很复杂的事情.如果再讲得枯燥,那么就会更让人昏昏欲睡了.本文希望能尽量用稍 ...

  5. 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.1

    HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...

  6. TCP/IP基础

    TCP/IP 是用于因特网 (Internet) 的通信协议. 计算机通信协议是对那些计算机必须遵守以便彼此通信的规则的描述. 什么是 TCP/IP? TCP/IP 是供已连接因特网的计算机进行通信的 ...

  7. TCP/IP之TCP_NODELAY与TCP_CORK

    TCP/IP之Nagle算法与40ms延迟提到了Nagle 算法.这样虽然提高了网络吞吐量,但是实时性却降低了,在一些交互性很强的应用程序来说是不允许的,使用TCP_NODELAY选项可以禁止Nagl ...

  8. TCP/IP之Nagle算法与40ms延迟

    Nagle算法是针对网络上存在的微小分组可能会在广域网上造成拥塞而设计的.该算法要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组确认到达之前不能发送其他的小分组.同时,TCP收集这 ...

  9. TCP的数据传输小结

    TCP的交互数据流 交互式输入 通常每一个交互按键都会产生一个数据分组,也就是说,每次从客户传到服务器的是一个字节的按键(而不是每次一行) 经受时延的确认 通常TCP在接受到数据时并不立即发送ACK: ...

  10. TCP服务和首部知识点小结

    服务 应用程序会被TCP分割成数据段,而UDP不分割. TCP有超时重传和确认 如果检验和出错将丢弃 IP数据包可能会失序或者重复,所以TCP会处理 滑动窗口来进行流量控制 对字节流的内容不做任何解释 ...

随机推荐

  1. 网络体系之TCP/IP模型

    TCP/IP参考模型是因特网使用的参考模型,这个体系结构在它的两个主要协议出现以后,被称为TCP/IP参考模型.该模型将网络协议分为四层:网络接口层.网络层.运输层.应用层. TCP/IP协议不是TC ...

  2. 9.27-uname,useradd命令

    打印系统信息 [root@wen ~]# uname Linux [root@wen ~]# uname -r #内核版本 2.6.32-573.el6.x86_64 [root@wen ~]# un ...

  3. hdu 5181 numbers——思路+区间DP

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5181 题解:https://www.cnblogs.com/Miracevin/p/10960717.ht ...

  4. g++ 之 -m64选项

    今天编译之前的项目,竟然报了下面的错误 usr/bin/ld: i386 architecture of input file `./proxycpp/soapRemoteDiscoveryBindi ...

  5. 报警插件Alertmanager 安装与使用

    Alertmanager是一个独立的告警模块,接收Prometheus等客户端发来的警报,之后通过分组.删除重复等处理,并将它们通过路由发送给正确的接收器:告警方式可以按照不同的规则发送给不同的模块负 ...

  6. LeetCode 最短无序连续子数组

    题目链接:https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/ 题目大意: 略. 分析: 如果排序区间为 [L ...

  7. ThinkPHP3.2.3 目录介绍

    ThinkPHP3.2.3 目录介绍,在开发中主要操作的目录就是在入口文件www/index.php中定义的www/application/文件目录了. www  WEB部署目录 ├─index.ph ...

  8. C++中的面向对象(一)

    1,本节课开始进入 C++ 中的面向对象,面向对象是 C++ 中最核心也是体现 C++ 价   值的一个部分: 2,日常生活当中我们都习惯对事物进行分类,那么这种分类的思想是否可以引入到 程序设计中? ...

  9. css设置图片的高等于图片的高

    <div class="box"> <img src="img/2222.jpg" /> </div> .box { pos ...

  10. 使用雪花算法为分布式下全局ID、订单号等简单解决方案考虑到时钟回拨

    1.snowflake简介         互联网快速发展的今天,分布式应用系统已经见怪不怪,在分布式系统中,我们需要各种各样的ID,既然是ID那么必然是要保证全局唯一,除此之外,不同当业务还需要不同 ...