tcp/ip通信第5期之服务器端程序
/*
此程序是tcp/ip通信服务器端程序,测试运行在redhat5上
重构readline函数,解决粘包问题——利用“\n”识别一个消息边界
*/ #include<stdio.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
#include<errno.h> ssize_t readn(int fd, void *buf, size_t count)
{
size_t nleft = count;//还留下多少字节没有读
ssize_t nread; //已经读了多少字节
char *bufp = (char *)buf;
while (nleft > )
{
if ((nread = read(fd, bufp, nleft)) < )
{
if (errno == EINTR)
//被信号中断,errno这个全局变量的值就会等于EINTR。
continue;
return -;
}
else if (nread == ) //对方关闭或者已经读到eof
return count - nleft;
bufp += nread;
nleft -= nread;
}
return count;
} ssize_t writen(int fd, const void * buf, size_t count)
{
size_t nleft = count;
ssize_t nwritten;
char *bufp = (char *)buf;
while (nleft > )
{
if ((nwritten = write(fd, bufp, nleft)) < )
{
if (errno == EINTR)
continue;
//要保证读取的字节数为指定字节数,所以继续
return -;
}
else if (nwritten == )
continue;
//由于其他原因引起的什么都没有写进,则继续操作,保证指定字节数
bufp += nwritten;
nleft -= nwritten;
}
return count;
} ssize_t recv_peek(int sockfd,void *buf,size_t len)
{
while()
{
int ret=recv(sockfd,buf,len,MSG_PEEK);
if(ret==-&&errno==EINTR)
continue;
return ret;
}
} ssize_t recv_line(int sockfd,void *buf,size_t len)
{
int ret;//记录函数返回值
int nread;//已经读到的字节数
char *bufp=buf;
int nleft=len;
while()
{
ret=recv_peek(sockfd,bufp,nleft);
if(ret<)
return ret;
else if(ret==)
return ret;
nread=ret;
int i;
for(i=;i<nread;i++)
{
if(bufp[i]=='\n')
{
ret=readn(sockfd,bufp,i+);
if(ret!=i+)
exit();
return ret;
}
}
if(nread>nleft)
exit();
nleft -= nread;
ret=readn(sockfd,bufp,nread);
if(ret!=nread)
exit();
bufp+=nread;
}
return -;
} #define port 5188
int main()
{
int listenfd;
//*****创建套接字*******
if((listenfd=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<)
/*if((listenfd=socket(PF_INET,SOCK_STREAM,0))<0)*/
perror("error"); //*******ipv4地址结构**********
struct sockaddr_in servaddr;
memset(&servaddr,,sizeof(servaddr)); //清空结构体变量
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(port); //使用端口号:5188
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY表示使用本机的任意可用ip地址,转换成网络地址序
/*servaddr.sin_addr.s_addr = inet_addr("127.168.0.12");*/
/*inet_aton("127.168.0.12",&servaddr.sin_addr);*/ //*******绑定套接字和本机地址***********
//1、设置REUSEADDR选项
int N=;
if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&N,sizeof(N))<)
perror("error");
//2、进行绑定
if(bind(listenfd,(struct sockaddr*)(&servaddr),sizeof(struct sockaddr))<)
perror("error"); //********将绑定的套接字转换为监听状态********
if(listen(listenfd,SOMAXCONN)<) //SOMAXCONN这个宏表示最大队列值
perror("error");
/*一旦调用listen函数,那么这个套接字就变成了被动套接字(只能被动接受连接——accept,
不能发起连接——connect),否则还是主动套接字(可以发起连接——connect)*/ //********接收对方的连接请求**************
struct sockaddr_in peeraddr; //定义对方地址
socklen_t peerlen=sizeof(peeraddr);
int con;
if((con=accept(listenfd,(struct sockaddr*)(&peeraddr),&peerlen))<)
perror("error");
else
printf("client_ip=%s,client_port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port)); //*******数据通信过程***********
char recvbuf[];
while()
{
memset(recvbuf,,sizeof(recvbuf));
int ret=recv_line(con,recvbuf,sizeof(recvbuf));//con这里是已连接套接字,不再是被动套接字,而是主动套接字了
if(ret==-)
exit();
if(ret==)
{
printf("client_port is closed.\n");
break;
}
fputs(recvbuf,stdout);
writen(con,recvbuf,strlen(recvbuf));
memset(recvbuf,,sizeof(recvbuf));
}
close(con);
close(listenfd);
return ; }
tcp/ip通信第5期之服务器端程序的更多相关文章
- tcp/ip通信第5期之客户机端程序
/*此程序是tcp/ip通信的客户机端程序, 测试运行在redhat6系统上 重构readline函数,解决粘包问题——利用“\n”识别一个消息边界 */ #include<stdio.h> ...
- TCP/IP通信过程(以发送电子邮件为例)(转)
1.应用程序处理 (1)A用户启动邮件应用程序,填写收件人邮箱和发送内容,点击“发送”,开始TCP/IP通信: (2)应用程序对发送的内容进行编码处理,这一过程相当于OSI的表示层功能: (3)由A用 ...
- TCP/IP 通信
TCP/IP 通信又叫socket 通信,是基于TCP/IP协调面向连接的一个数据传输技术.是属于OSI国际标准的传输层,三次握手 提供数据,有序,安全,端到端的传输和接收.它有三个主要协议:传输控制 ...
- linux高性能服务器编程 (四) --TCP/IP通信案例
第四章 TCP/IP通信案例 HTTP代理服务器的大致工作原理 在HTTP通信链上,客户端和服务器之间通常存在某些中转代理服务器.它们提供对目标资源的中转访问.一个HTTP请求可能被多个 ...
- 使用Boost asio实现同步的TCP/IP通信
可以先了解一下Boost asio基本概念,以下是Boost asio实现的同步TCP/IP通信: 服务器程序部分,如果想保留套接字之后继续通信,可以动态申请socket_type,保存指针,因为so ...
- 使用Boost asio实现异步的TCP/IP通信
可以先了解一下Boost asio基本概念,以下是Boost asio实现的异步TCP/IP通信: 服务器: #include "stdafx.h" #include <io ...
- 第4章 TCP/IP通信案例:访问Internet上的Web服务器
第4章 TCP/IP通信案例:访问Internet上的Web服务器 4.2 部署代理服务器 书中为了演示访问Internet上的Web服务器的全过程,使用了squid代理服务器程序模拟了一个代理服务器 ...
- TCP/IP通信网络基础
TCP/IP是互联网相关的各类协议族的总称. TCP/IP的分层管理 分层的优点:如果只有一个协议在互联网上统筹,某个地方修改就要把所有的部分整体换掉,采用分层则只需要改变相应的层.把各个接口部分规划 ...
- tcp/ip通信传输流
利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信,发送端从应用层往下走,接收端则往应用层方向走. 我们用HTTP进行举例 客户端在应用层发出想要看到某个web页面的http请求.HT ...
随机推荐
- [转]USB之Part 4 - Protocol
原地址http://www.usbmadesimple.co.uk/ums_4.htm Controlling a Device Before we go into detail, we need t ...
- django 使用mysql 数据库
在 django 创建项目中 默认使用的是 splite3 数据库,不是mysql 数据库,要使用mysql ,要做一些配置: 在 settings.py 中修改如下: DATABASES = { ...
- 如何创建一个django工程与和mysql打通
1. 安装Django # 在指定解释器环境下安装django 1.11.x # 在真实python3环境下: pip3 install django==1.11.x # 查看django版本: dj ...
- MySql Delete不走索引问题
如果delete语句带有查询,写法不对会导致不走索引. 简单粗暴的办法:拆两条sql,一条查询,一条delete ======================= [不走索引的写法] DELETE FR ...
- CentOS 7.0安装配置Vsftp服务器步骤详解
安装Vsftp讲过最多的就是在centos6.x版本中了,这里小编看到有朋友写了一篇非常不错的CentOS 7.0安装配置Vsftp服务器教程,下面整理分享给各位. 一.配置防火墙,开启FTP服务器需 ...
- ABAP-串口通信-道闸设备
最近SAP系统需要与道闸设备集成,通过串口通讯模式控制道闸栏杆升降,在此将开发过程中的思路及问题点做个备注. 一.相关设备 道闸设备型号:富士智能FJC-D618 串口模块:康耐德 C2000-A1- ...
- Python的几种主流框架
参考:https://www.cnblogs.com/linkenpark/p/5881586.html
- mongo aggregate 用法记录
mongo 聚合查询查询还是很方便的,做下记录 依赖的jar是org.springframework.data.mongodb 1.9.6 低版本可能不支持. 数据结构 大概是 这是一份 ...
- spring获取配制文件的参数
项目中需要获取一些万年不变的参数,比如单点登录的域名 怎么从多个文件配置中获取呢,原来spring早已经提供了类PropertyPlaceholderConfigurer <?xml versi ...
- MyEclipse反向生成Java代码 ,Reverse Engineering-->Java Source Folder-->没有提供任何条目
在web项目名称上,手动执行一遍Add Hibernate Capabilities,然后再去DB Browser中进行反向生成pojo实体类和hbm.xml映射文件!,具体生成反向代码的配置如下图所 ...