/*此程序是tcp/ip通信的客户机端程序,
测试运行在redhat6系统上
重构readline函数,解决粘包问题——利用“\n”识别一个消息边界
*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<signal.h>
#include<errno.h> #define port 5188 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 -;
} int main()
{
int sock;
//*****创建套接字*******
if((sock=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=inet_addr("192.168.248.129"); //ip地址使用对方的地址,即服务器地址
printf("the port_id:%d\n",port); //*********连接请求************
if(connect(sock,(struct sockaddr*)(&servaddr),sizeof(servaddr))<) //使用对方的ip地址
perror("error");
else
printf("connected success.\n"); //************通信过程*************
char sendbuf[]={};
char recvbuf[]={};
while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)
{
writen(sock,sendbuf,strlen(sendbuf));
int ret=recv_line(sock,recvbuf,sizeof(recvbuf));
if(ret==-)
perror("error\n");
if(ret==)
{
printf("peer is closed.\n");
break;
} fputs(recvbuf,stdout);
memset(sendbuf,,sizeof(sendbuf)); //清空缓存
memset(recvbuf,,sizeof(recvbuf));
}
close(sock);
return ;
}

tcp/ip通信第5期之客户机端程序的更多相关文章

  1. tcp/ip通信第5期之服务器端程序

    /* 此程序是tcp/ip通信服务器端程序,测试运行在redhat5上 重构readline函数,解决粘包问题——利用“\n”识别一个消息边界 */ #include<stdio.h> # ...

  2. TCP/IP 通信

    TCP/IP 通信又叫socket 通信,是基于TCP/IP协调面向连接的一个数据传输技术.是属于OSI国际标准的传输层,三次握手 提供数据,有序,安全,端到端的传输和接收.它有三个主要协议:传输控制 ...

  3. 第4章 TCP/IP通信案例:访问Internet上的Web服务器

    第4章 TCP/IP通信案例:访问Internet上的Web服务器 4.2 部署代理服务器 书中为了演示访问Internet上的Web服务器的全过程,使用了squid代理服务器程序模拟了一个代理服务器 ...

  4. linux高性能服务器编程 (四) --TCP/IP通信案例

    第四章 TCP/IP通信案例 HTTP代理服务器的大致工作原理        在HTTP通信链上,客户端和服务器之间通常存在某些中转代理服务器.它们提供对目标资源的中转访问.一个HTTP请求可能被多个 ...

  5. TCP/IP通信网络基础

    TCP/IP是互联网相关的各类协议族的总称. TCP/IP的分层管理 分层的优点:如果只有一个协议在互联网上统筹,某个地方修改就要把所有的部分整体换掉,采用分层则只需要改变相应的层.把各个接口部分规划 ...

  6. 使用Boost asio实现同步的TCP/IP通信

    可以先了解一下Boost asio基本概念,以下是Boost asio实现的同步TCP/IP通信: 服务器程序部分,如果想保留套接字之后继续通信,可以动态申请socket_type,保存指针,因为so ...

  7. 使用Boost asio实现异步的TCP/IP通信

    可以先了解一下Boost asio基本概念,以下是Boost asio实现的异步TCP/IP通信: 服务器: #include "stdafx.h" #include <io ...

  8. TCP/IP通信过程(以发送电子邮件为例)(转)

    1.应用程序处理 (1)A用户启动邮件应用程序,填写收件人邮箱和发送内容,点击“发送”,开始TCP/IP通信: (2)应用程序对发送的内容进行编码处理,这一过程相当于OSI的表示层功能: (3)由A用 ...

  9. 1 TCP/IP通信

    重点参考长链接http://blog.csdn.net/fengyuzhengfan/article/details/38830115 http://blog.csdn.net/Jsagacity/a ...

随机推荐

  1. 选择、操作web元素

    11月1日 什么是web元素 Selenium自动化主要就是:选择界面元素,操作界面元素(输入操作:点击.输入文字.拖拽等,输出操作:获取元素的各种属性),根据界面上获取的数据进行分析和处理 选择元素 ...

  2. 机器学习入门-数值特征-对数据进行log变化

    对于一些标签和特征来说,分布不一定符合正态分布,而在实际的运算过程中则需要数据能够符合正态分布 因此我们需要对特征进行log变化,使得数据在一定程度上可以符合正态分布 进行log变化,就是对数据使用n ...

  3. Python运算符,基本数据类型

    1,基本的运算符: 加,减,乘,除 取余(%)   取商(//)   **(幂) in    not in (判断是否在里面) 1.运算符        结果是值            算数运算   ...

  4. C语言复习:结构体

    结构体专题 01.结构体类型定义及结构体变量定义     char c1,char c2, char name[62]; int age     char name[62]; int age,char ...

  5. C#开发VS LUA开发

    一个游戏公司,决定开始用U3D做一款新游戏,这个游戏类型从来没做过. 如果没有一个成熟的游戏框架,那么从头撸起. 是一开始就将LUA热更新考虑进来呢 还是先做成纯C#的框架呢? 考虑因素:游戏逻辑如果 ...

  6. idea将项目打成war包

    idea将项目打成war包(转载) 2018年02月28日 20:08:03 沈行的专栏 阅读数:13773更多 个人分类: Java   首先点击这里进入项目的配置页面 在Artifacts栏里点击 ...

  7. RabbitMQ系列教程之六:远程过程调用(RPC)(转载)

    RabbitMQ系列教程之六:远程过程调用(RPC) 远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习 ...

  8. 自定义标签在IE6-8的困境

    或许未来前端组件化之路都是自定义标签,但这东西早在20年前,JSTL已在搞了.现在Web Component还只有webkit支持.但一个组件库,还需要一个特殊的标识它们是一块的.不过这个XML已经帮 ...

  9. 关于malloc(0)的返回值问题--这两天的总结与实践篇

    就像我在http://www.cnblogs.com/wuyuegb2312/p/3219659.html 文章中评论的那样,我也碰到了被提问这个malloc(0)的返回值问题,虽然感觉这样做在实际中 ...

  10. python3.6安装-windows

    1.打开python官网 2.找到下载链接 3.选择对应的版本下载 4.下载完成后打开安装包并执行,运行出该界面. 5.这里是安装到C盘上(默认安装) 6.此处为自定义安装 7.选择自定义安装,并全选 ...