然后基本的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. jenkins部署github项目持续集成

    一.先介绍正向代理和反向代理 正向代理 反向代理 二.安装反响代理得到固定域名 http://www.xiaomiqiu.cn/ 三.Jenkins与Github集成 配置前要求: 1.Jenkins ...

  2. DM9000网卡驱动深度分析

    一.dm9000_porbe函数分析 不同于u-boot代码,tq2440中的DM9000更加复杂,需要分析的点也很多: /* * Search DM9000 board, allocate spac ...

  3. CF 936C Lock Puzzle——构造

    题目:http://codeforces.com/contest/936/problem/C 玩了一个小时,只能想出 5*n 的方法. 经过一番观察?考虑这样构造:已经使得 A 串的一个后缀 = B ...

  4. 汉诺塔IX

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=76447#problem/E 汉诺塔IX Time Limit:1000MS     Me ...

  5. [CSP-S模拟测试73]题解

    A.小P的2048 作为一个看B哥玩了一个寒假的人这种题闭眼切好吧 模拟即可.程序模块化后直接复制粘贴. 说什么模拟不能复制粘贴的都没水平 #include<cstdio> #includ ...

  6. JS当中的无限分类递归树

    列表转换成树形结构方法定义: //javascript 树形结构 function toTree(data) { // 删除 所有 children,以防止多次调用 data.forEach(func ...

  7. Windwos 08R2_DNS全面图文详解

    目录 目录 前言 软件环境 DNS域名服务器 DNS服务器原理 DNS域名空间 DNS区域 DNS服务器的类别 DNS查询模式 缓存文件 配置DNS服务器 DNS服务的应用 创建DNS正向解析区域 在 ...

  8. C++内存修改器开源代码

    我们玩单机游戏时,游戏难度可能过大, 或者游戏已经比较熟练,想要增加游戏的玩法,这时候可以使用修改器. 内存式游戏修改器主要对游戏内存修改 修改时有两种方式,一是定时对内存数值进行修改.实现类似锁定的 ...

  9. spring boot 尚桂谷学习笔记06 异常处理 ---Web

    ------错误处理机制------ 默认效果 1 返回一个默认的错误页面 浏览器发送请求的请求头:优先接收 text/html 数据 客户端则默认响应json数据 : accept 没有说明返回什么 ...

  10. pandas相关操作

    import pandas as pd import numpy as np ''' 一.创建df 1.定义df :传递字典 1.1每一列的名称作为键 每个键都有一个数组作为值[key:数组] 1.2 ...