TCP/IP编程——基于TCP的半关闭
在TCP服务端和客户端建立连接之后服务端和客户端会分别有两个独立的输入流和输出流,而且相互对应。服务端的输出流对应于客户端的输入流,服务端的输入流对应于客户端的输出流。这是在建立连接之后的状态。
当我们调用close()函数时,系统会同时把双方的输入流和输出流全部关闭,但是有时候我们仍需要在一方断开连接之后只进行接受数据或者传输数据其中一项操作。这时就需要我们只断开输入或者输出,保留另一个流的正常运转,也就引入了TCP的半关闭状态。
基本操作:
之前我们传输完数据之后便直接调用了close()函数,我们可以使用系统提供的shutdown()函数方便的完成TCP的半关闭。
shutdown(int socket , int type):半关闭套接字中的输入或者输出流
- socket(套接字描述符):需要断开的套接字描述符
- type(断开类型):套接字的断开方式
SHUT_RD——断开输入流,并清空输入缓冲中的数据
SHUT_WR——断开输出流,并将输出缓冲中的数据输出
SHUT_RDWR——同时断开输入输出流,分两次调用shutdown()函数
成功时返回0,失败时返回-1
服务端:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h> #define BUFF_SIZE 30 void error_handling(char *message); /**
基于TCP的半连接服务端
**/
int main(int argc ,char *argv[]){
//客户端和服务端的socket描述符
int serv_sock;
int clent_sock;
//客户端和服务端的地址
struct sockaddr_in serv_addr;
struct sockaddr_in clent_addr;
//客户端地址大小
socklen_t client_addr_size;
//用于记录读取的文件字节数
int read_count;
//缓冲大小
char buff[BUFF_SIZE];
//用于打开文件的文件指针
FILE *fp;
//检查输入的参数个数是否合法
if(argc!=2){
printf("Usage : %s <port> \n ",argv[0]);
exit(1);
} //使用文件描述符打开文件
fp = fopen("word_file.txt","rb");
//创建服务端saocket
serv_sock = socket(AF_INET,SOCK_STREAM,0);
//将server_addr中的内容清空
memset(&serv_addr,0,sizeof(serv_addr));
//初始化socket地址
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(argv[1])); //进行地址绑定
if(bind(serv_sock,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) == -1){
error_handling("bind() error");
}
//使服务端进入监听状态
if(listen(serv_sock,5) == -1){
error_handling("listen() error");
}
//获的客户端地址的大小
client_addr_size = sizeof(clent_addr);
clent_sock = accept(serv_sock,(struct sockaddr *) &clent_addr,&client_addr_size); while(1){
//读取的文件字节数
read_count = fread((void *) buff,1,BUFF_SIZE,fp);
//向客户端写入数据
if(read_count<BUFF_SIZE){
write(clent_sock,buff,read_count);
break;
}
write(clent_sock,buff,BUFF_SIZE);
}
/**
在数据输出完成之后,对输出流进行流半关闭
这种状态下服务读不能向客户端写入数据,但是可以接受来自客户端的数据
**/
shutdown(clent_sock,SHUT_WR);
//接受来自客户端的消息
while(0 == read(clent_sock,buff,BUFF_SIZE))
{
continue;
}
//打印消息
printf("Message from client : %s \n",buff);
//关闭文件
fclose(fp);
write(clent_sock,"11111",5);
//彻底关闭TCP连接
//close(clent_sock);
//close(serv_sock);
//避免因进程退出,导致 server 向 client 发 FIN
while(1){};
return 0;
} void error_handling(char * message){
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}
客户端:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h> #define BUFF_SIZE 30 void error_handling(char *message); int main(int argc ,char *argv[]){
int sock;
FILE *fp; char buff[BUFF_SIZE];
int read_count;
struct sockaddr_in server_addr; if(argc!=3){
printf("Usage : %s <port> \n ",argv[0]);
exit(1);
} fp = fopen("recevice.dat","wb");
sock = socket(AF_INET,SOCK_STREAM,0); memset(&server_addr,0,sizeof(server_addr)); //初始化socket地址
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2])); connect(sock,(struct sockaddr *) &server_addr,sizeof(server_addr)); while(read_count = read(sock,buff,BUFF_SIZE) != 0){
//向文件中写入读取到的数据
printf("recv data from server : %s\n",buff);
fwrite((void *) buff,1,read_count,fp);
}
//打印接收到的数据
puts("Recevied file data");
//接收完成之后向服务端发送一个消息
// 睡3秒,确保server端 shutdown()已执行
sleep(3);
write(sock,"Thank you ",10);
write(sock,"server",6); //关闭文件和socket连接
fclose(fp);
// 避免因进程退出,导致 client 向 server 发 FIN
while(1){};
//close(sock);
return 0;
} void error_handling(char * message){
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}
至此就完成了一个基于半关闭的TCP服务端/客户端程序,这样使得服务端在传输完数据之后可以只保留输入流,关闭输出流。
抓包:https://files.cnblogs.com/files/yorkyang/tcp%E5%8D%8A%E5%85%B3%E9%97%AD.zip
转自:http://blog.csdn.net/wqc_csdn/article/details/51543504
TCP/IP编程——基于TCP的半关闭的更多相关文章
- linux tcp/ip编程和windows tcp/ip编程差别以及windows socket编程详解
最近要涉及对接现有应用visual c++开发的tcp客户端,花时间了解了下windows下tcp开发和linux的差别,从开发的角度而言,最大的差别是头文件(早期为了推广尽可能兼容,后面越来越扩展, ...
- 网络编程(二)——TCP协议、基于tcp协议的套接字socket
TCP协议与基于tcp协议的套接字socket 一.TCP协议(流式协议) 1.可靠传输,TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的 ...
- Java 网络编程 -- 基于TCP 模拟多用户登录
Java TCP的基本操作参考前一篇:Java 网络编程 – 基于TCP实现文件上传 实现多用户操作之前先实现以下单用户操作,假设目前有一个用户: 账号:zs 密码:123 服务端: public c ...
- TCP/IP笔记(二)TCP/IP简介
上回,主要介绍了下协议和OSI参考模型,并简单了解下网络构成要素,这回该说说TCP/IP了 互联网与TCP/IP的关系 互联网进行通信时,需要相应的网络协议,TCP/IP原本就是为使用互联网而开发 ...
- TCP/IP 协议图--TCP/IP 基础
1. TCP/IP 的具体含义 从字面意义上讲,有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议.实际生活当中有时也确实就是指这两种协议.然而在很多情况下,它只是利用 IP 进行通信时所 ...
- tcp/ip学习笔记-TCP
tcp/ip学习笔记-TCP 彭会锋 报文发送采用的是tcp_output函数,
- TCP/IP协议图--TCP/IP基础
1. TCP/IP 的具体含义 从字面意义上讲,有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议.实际生活当中有时也确实就是指这两种协议.然而在很多情况下,它只是利用 IP 进行通信时所 ...
- OSI参考模型与TCP/IP参考模型与TCP/IP协议栈
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11484126.html OSI参考模型与TCP/IP参考模型与TCP/IP协议栈 TCP/IP分层模型 ...
- 20181225 基于TCP/IP和基于UDP/IP的套接字编程
一.TCP/IP的套接字编程 服务器端代码: import socketserver = socket.socket() # 默认是基于TCP# 基于TCP的对象serve=socket.sock ...
随机推荐
- Centos6.5建立本地YUM源
很多情况下公司的服务器是不允许连外网的,那么安装软件的时候就很不方便了,这里就需要建立一个本地YUM源了. 文件位置:/etc/yum.repos.d/ 后缀一定是.repo结束. 下面我们搭建 ...
- 数据分析与挖掘 - R语言:贝叶斯分类算法(案例一)
一个简单的例子!环境:CentOS6.5Hadoop集群.Hive.R.RHive,具体安装及调试方法见博客内文档. 名词解释: 先验概率:由以往的数据分析得到的概率, 叫做先验概率. 后验概率:而在 ...
- cocos2d JS-(JavaScript) 类型检测与判断
//检测类型 var str = "Hello World"; if (typeof str=="string") {//使用typeof来判断对象类型的一个例 ...
- DataGrip设置长sql语句自动换行
我这个DataGrip是英文版的. 在每个查询窗口(Console)的工具图标里,有个Settings.打开Settings弹出框,试图从Appearance和Editor里找到设置选项,却没有找到. ...
- 网络编程之Socket的TCP协议实现客户端与客户端之间的通信
我认为当你学完某个知识点后,最好是做一个实实在在的小案例.这样才能更好对知识的运用与掌握 如果你看了我前两篇关于socket通信原理的入门文章.我相信对于做出我这个小案列是完全没有问题的!! 既然是小 ...
- 独立出properties的mybatis连接池
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/java505?useSSL=true&chara ...
- 008-副文本编辑器UEditor
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- Opcode是啥以及如何使用好Opcache
转载 https://www.zybuluo.com/phper/note/1016714 啥是Opcode? 我们在日常的PHP开发过程中,应该经常会听见Opcache这个词,那么啥是Opcode ...
- c++ string split
#include <iterator> #include <regex> std::vector<std::string> s_split(const std::s ...
- 17. Letter Combinations of a Phone Number(bfs)
Given a string containing digits from 2-9 inclusive, return all possible letter combinations that th ...