第四章 基本TCP套接字编程 第五章 TCP客户/服务器程序实例
TCP客户与服务器进程之间发生的重大事件时间表
TCP服务器
socket() --- bind() --- listen() --- accept() --- read() --- write --- read() --- close
TCP客户
socket() --- connect() --- write() --- read() --- close()
套接字函数简介
int socket(int family, int type, int protocol);
指定要用的通信协议类型
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
客户用connect()来建立与TCP服务器的连接
int bind(int sockfd, const struct sockaddr *myaddr, scoklen_t addrlen);
把一个本地协议地址赋予一个套接字
int listen(int sockfd, int backlog);
设置套接字为被动套接字,指示内核接收向该套接字的连接请求
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
由TCP服务器调用, 用来从已完成连接队列队头返回下一个已完成连接
pid_t fork(void);
产生子进程
int close(int sockfd);
关闭套接字, 并终止TCP连接
典型的并发服务器程序轮廓
pid_t pid;int listenfd, connfd;listenfd=Socket(...);Bind(listenfd, ...);Listen(listenfd,LISTENQ);for(;;){connfd=Accept(listenfd, ...);if((pid=Fork())==0){//如果是子进程Close(listenfd);//子进程关闭其监听套接字doit(connfd);//处理需求Close(connfd);//关闭子进程的已连接套接字exit(0);//子进程终止}Close(connfd);//父进程关闭已连接套接字}
TCP echo服务器程序
#include "unp.h"#include <time.h>void srv_echo(int sockfd){ssize_t n;char buf[1000];again:while((n=read(sockfd,buf,1000))>0)Writen(sockfd,buf,n);if(n<0 && errno==EINTR)goto again;else if(n<0)err_sys("srv_echo: read error");}intmain(int argc,char ** argv){int listenfd, connfd;pid_t childpid;socklen_t clilen;struct sockaddr_in cliaddr, servaddr;char buff[1000];listenfd=Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family=AF_INET;servaddr.sin_addr.s_addr=htonl(INADDR_ANY);servaddr.sin_port=htons(1234);Bind(listenfd, (SA*) &servaddr, sizeof(servaddr));Listen(listenfd, 100);for(;;){clilen=sizeof(cliaddr);connfd=Accept(listenfd, (SA*) &cliaddr, &clilen);printf("connection from %s , port %d\n",inet_ntop(AF_INET,&cliaddr.sin_addr, buff, sizeof(buff)),ntohs(cliaddr.sin_port));if((childpid=Fork())==0){Close(listenfd);srv_echo(connfd);exit(0);}Close(connfd);}}
TCP echo客户端程序
#include "unp.h"void cli_echo(FILE *fp, int sockfd){char sendline[1000], recvline[1000];while(Fgets(sendline,1000, fp)!=NULL){Writen(sockfd, sendline, strlen(sendline));if(Readline(sockfd, recvline, 1000)==0)err_quit("cli_echo: server terminated prematurely");Fputs(recvline, stdout);}}intmain(int argc, char **argv){int sockfd;struct sockaddr_in servaddr;if(argc!=2)err_quit("usage: tcpcli <IPaddress>");sockfd=Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family=AF_INET;servaddr.sin_port=htons(1234);Inet_pton(AF_INET,argv[1], &servaddr.sin_addr);Connect(sockfd, (SA*) &servaddr, sizeof(servaddr));cli_echo(stdin,sockfd);exit(0);}
这一章的API讲解非常有逻辑性, 讲解的过程可以看到这样设计的合理性
4.5 listen函数
当一个客户的SYN到达, 若服务器的相应监听套接字维护的队列已经满了, TCP就会忽略该分节, 也就是不发送RST. (这里的TCP指的是实现TCP的内核)
之所以这样设计有两点理由:
(1)这种情况是暂时的, TCP的正常重传机制会处理这个问题
(2)客户无法区分这个RST意思是 "该端口没有服务器在监听" 还是 "该端口有服务器在监听, 不过队列已满"
第四章 基本TCP套接字编程 第五章 TCP客户/服务器程序实例的更多相关文章
- 【UNIX网络编程(四)】TCP套接字编程具体分析
引言: 套接字编程事实上跟进程间通信有一定的相似性,可能也正由于此.stevens这位大神才会将套接字编程与进程间的通信都归为"网络编程",并分别写成了两本书<UNP1> ...
- 基本套接字编程(1) -- tcp篇
1. Socket简介 Socket是进程通讯的一种方式,即调用这个网络库的一些API函数实现分布在不同主机的相关进程之间的数据交换. 几个定义: (1)IP地址:即依照TCP/IP协议分配给本地主机 ...
- UNP学习笔记1——基本TCP套接字编程
1 套接字地址结构 大多数套接字函数都需要一个指向套接字地址结构的指针作为参数.每个协议族都定义了自己的套接字结构.这些套接字的结构以sockaddr_开头,以每个协议族唯一的后缀名结尾. 1.1 I ...
- TCP套接字编程模型及实例
摘要: 本文讲述了TCP套接字编程模块,包括服务器端的创建套接字.绑定.监听.接受.读/写.终止连接,客户端的创建套接字.连接.读/写.终止连接.先给出实例,进而结合代码分析. PS:本文权当 ...
- UNP学习笔记(第四章 基本TCP套接字编程)
本章讲解编写一个完整的TCP客户/服务器程序所需要的基本套接字函数. socket函数 #include <sys/socket.h> int socket(int family,int ...
- unix网络编程第四章----基于TCP套接字编程
为了执行网络I/O操作.进程必须做的第一件事情就是调用Socket函数.指定期待的通信协议 #include<sys/socket.h> int socket(int family,int ...
- UNP——第四章,TCP套接字编程
1.socket 函数 首先被调用的函数,用于选择通信协议. socket调用成功后,得到的套接字为主动套接字CLOSED状态. PF 和 AF 的关系 PF的是协议族,AF是地址族,理论上一个PF包 ...
- 初探网络编程--TCP套接字编程演示
今天看了一下<计算机网络:自顶向下方法>,也就是计算机网络的教材的应用层一章,决定实现以下后面的Java C/S应用程序的例子,用来演示TCP和UDP套接字编程. 程序流程如下: 1.一台 ...
- TCP套接字编程
一.套接字(socket)函数 图1给出了在一个TCP客户与服务器通信的流程.服务器首先启动,稍后某个客户启动,它试图连接到服务器.假设客户给服务器发送一个请求,服务器处理该请求,并且给客户发回一个相 ...
随机推荐
- Java 之 IO 异常的处理【了解】
一.JDK7 前的处理 前面的 Demo 中,一直把异常抛出,而在实际中并不能这样处理,建议使用 try...catch...finally 代码块,处理异常部分. 格式: try{ 可能会产出异常的 ...
- Intellij里检出svn报错找不到svn解决办法
Intellij里检出svn报错找不到,解决办法: 1. 安装svn客户端: 2. 去掉settings->version control->subversion里的use command ...
- linux USB 编程
Linux USB架构 可以看出一个USB体系需要4个驱动:USB设备驱动(主要编写这部分),USB主控制器驱动,Gadget驱动,UDC驱动. USB主要有4个功能: MassStorage:大容量 ...
- Mac下多版本JDK安装及管理
在Java项目中,经常对JDK版本有不同的要求,可是不可能为了某个项目的运行重新下载不同版本JDK进行安装,这样就涉及到对本地环境中多个JDK版本的管理. Mac的JDK都是安装到一个指定目录的:/L ...
- 分布式session的几种实现方式
在搭建完集群环境后,不得不考虑的一个问题就是用户访问产生的session如何处理.如果不做任何处理的话,用户将出现频繁登录的现象,比如集群中存在A.B两台服务器,用户在第一次访问网站时,Nginx通过 ...
- 在STM32F746G-DISCO开发板上使用Nabto + FreeRTOS的演示热泵应用
当使用STM32 ARM Cortex-M微控制器时,ST的免费嵌入式软件STM32Cube提供了所有必要的驱动程序和中间件组件,以减少初始的开发工作.在上述提到的中间件组件中,其中一个是非常受欢迎的 ...
- 解密Redis持久化【翻译】
本文来自Redis的作者,他在论坛看到大家对Redis持久化误解较大,所以写此文章论述持久化 写操作的流程 首先我们来看一下数据库在进行写操作时到底做了哪些事,主要有下面五个过程. 客户端向服务端发送 ...
- cookie和session基础知识学习
一.session的简单使用 session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个独享的session对象.session的使用步骤: 获取session对象使用session ...
- machine learning(13) -- solving the problem of overfitting:regularization
solving the problem of overfitting:regularization 发生的在linear regression上面的overfitting问题 发生在logistic ...
- vue npm,Git随笔
下载模块: npm install <package-name> --save-dev 上线: npm run build 基本使用流程:1. npm install vue-cli - ...