tcp/ip通信第5期之客户机端程序

  1 /*此程序是tcp/ip通信的客户机端程序,
  2   测试运行在redhat6系统上
  3   重构readline函数,解决粘包问题——利用“\n”识别一个消息边界
  4 */
  5 #include<stdio.h>
  6 #include<stdlib.h>
  7 #include<unistd.h>
  8 #include<sys/types.h>
  9 #include<sys/socket.h>
 10 #include<arpa/inet.h>
 11 #include<netinet/in.h>
 12 #include<string.h>
 13 #include<signal.h>
 14 #include<errno.h>
 15
 16 #define port 5188
 17
 18 ssize_t readn(int fd, void *buf, size_t count)
 19 {
 20     size_t nleft = count;//还留下多少字节没有读
 21     ssize_t nread; //已经读了多少字节
 22     char *bufp = (char *)buf;
 23     while (nleft > 0)
 24             {
 25                 if ((nread = read(fd, bufp, nleft)) < 0)
 26                 {
 27                     if (errno == EINTR)
 28  //被信号中断,errno这个全局变量的值就会等于EINTR。
 29                         continue;
 30                     return -1;
 31                 }
 32                 else if (nread == 0) //对方关闭或者已经读到eof
 33                     return count - nleft;
 34                 bufp += nread;
 35                 nleft -= nread;
 36             }
 37             return count;
 38 }
 39
 40 ssize_t writen(int fd, const void * buf, size_t count)
 41 {
 42         size_t nleft = count;
 43         ssize_t nwritten;
 44         char *bufp = (char *)buf;
 45         while (nleft > 0)
 46             {
 47                 if ((nwritten = write(fd, bufp, nleft)) < 0)
 48                 {
 49                     if (errno == EINTR)
 50                         continue;
 51  //要保证读取的字节数为指定字节数,所以继续
 52                     return -1;
 53                 }
 54                 else if (nwritten == 0)
 55                     continue;
 56  //由于其他原因引起的什么都没有写进,则继续操作,保证指定字节数
 57                 bufp += nwritten;
 58                 nleft -= nwritten;
 59             }
 60             return count;
 61 }
 62
 63 ssize_t recv_peek(int sockfd,void *buf,size_t len)
 64 {
 65     while(1)
 66     {
 67         int ret=recv(sockfd,buf,len,MSG_PEEK);
 68         if(ret==-1&&errno==EINTR)
 69             continue;
 70         return ret;
 71     }
 72 }
 73
 74 ssize_t recv_line(int sockfd,void *buf,size_t len)
 75 {
 76     int ret;//记录函数返回值
 77     int nread;//已经读到的字节数
 78     char *bufp=buf;
 79     int nleft=len;
 80     while(1)
 81     {
 82         ret=recv_peek(sockfd,bufp,nleft);
 83         if(ret<0)
 84             return ret;
 85         else if(ret==0)
 86             return ret;
 87         nread=ret;
 88         int i;
 89         for(i=0;i<nread;i++)
 90         {
 91             if(bufp[i]==‘\n‘)
 92             {
 93                 ret=readn(sockfd,bufp,i+1);
 94                 if(ret!=i+1)
 95                     exit(1);
 96                 return ret;
 97             }
 98         }
 99         if(nread>nleft)
100             exit(1);
101         nleft -= nread;
102         ret=readn(sockfd,bufp,nread);
103         if(ret!=nread)
104             exit(0);
105         bufp+=nread;
106     }
107     return -1;
108 }
109
110 int main()
111 {
112     int sock;
113     //*****创建套接字*******
114     if((sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
115     /*if((listenfd=socket(PF_INET,SOCK_STREAM,0))<0)*/
116         perror("error");
117
118     //*******ipv4地址结构**********
119     struct sockaddr_in servaddr;
120     memset(&servaddr,0,sizeof(servaddr)); //清空结构体变量
121     servaddr.sin_family=AF_INET;
122     servaddr.sin_port= htons(port); //使用端口号:5188
123     servaddr.sin_addr.s_addr=inet_addr("192.168.248.129");  //ip地址使用对方的地址,即服务器地址
124     printf("the port_id:%d\n",port);
125
126     //*********连接请求************
127     if(connect(sock,(struct sockaddr*)(&servaddr),sizeof(servaddr))<0)  //使用对方的ip地址
128         perror("error");
129     else
130         printf("connected success.\n");
131
132     //************通信过程*************
133     char sendbuf[1024]={0};
134     char recvbuf[1024]={0};
135     while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)
136     {
137         writen(sock,sendbuf,strlen(sendbuf));
138         int ret=recv_line(sock,recvbuf,sizeof(recvbuf));
139         if(ret==-1)
140             perror("error\n");
141         if(ret==0)
142         {
143             printf("peer is closed.\n");
144             break;
145         }
146
147         fputs(recvbuf,stdout);
148         memset(sendbuf,0,sizeof(sendbuf)); //清空缓存
149         memset(recvbuf,0,sizeof(recvbuf));
150     }
151     close(sock);
152     return 0;
153 }
时间: 2024-10-05 14:16:54

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

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

1 /* 2 此程序是tcp/ip通信服务器端程序,测试运行在redhat5上 3 重构readline函数,解决粘包问题——利用“\n”识别一个消息边界 4 */ 5 6 #include<stdio.h> 7 #include<netinet/in.h> 8 #include<arpa/inet.h> 9 #include<unistd.h> 10 #include<fcntl.h> 11 #include<sys/types.h>

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

可以先了解一下Boost asio基本概念,以下是Boost asio实现的同步TCP/IP通信: 服务器程序部分,如果想保留套接字之后继续通信,可以动态申请socket_type,保存指针,因为socket_type貌似不能拷贝: #include "stdafx.h" #include <iostream> #include <boost/asio.hpp> using namespace boost::asio; using namespace std;

NET使用SuperSocket完成TCP/IP通信(记录篇)

1)为什么使用SuperSocket? 性能高,易上手.有中文文档,我们可以有更多的时间用在业务逻辑上,SuperSocket有效的利用自己的协议解决粘包 2)SuperSocket的协议内容? 命令 body  列如:TestCommand 1 2 3)怎样在Net下使用 SuperSocket? 1)新建项目命名为SuperSocketWeb 2)引用程序集->NuGet工具搜索安装SuperSocket,SuperSocket.Engine两个组件 3)下载测试工具SocketTool 官

TCP/IP通信实现

网络层的IP协议提供不可靠通信服务.TCP协议则解决了分组的重传和排序问题. TCP通信特征 : 1)全双工,同时发送和接收数据 2)只支持两个端口之间的通信 3)基于字节流.对端无法知道报文的边界.例如发送4个512字节的数据,接收方并不清楚是4个512或是2个1024 TCP通信流程 来自为知笔记(Wiz)

TCP/IP通信过程

一.参考网址 二.TCP 1.例子: 192.168.22.66 telenet到192.168.22.74的tcp建立过程 1)SYN: 2)SYN+ACK 3)ACK 原文地址:https://www.cnblogs.com/shanyu20/p/11770436.html

一个TCP/IP通信的实例

1 /*服务器端*/ 2 #include<stdlib.h> 3 #include<stdio.h> 4 #include<string.h> 5 #include<errno.h> 6 #include<netdb.h> 7 #include<sys/types.h> 8 #include<netinet/in.h> 9 #include<sys/socket.h> 10 #include<unist

《图解TCP/IP》--TCP/IP协议分层模型与通信

本篇随笔只是粗略了解了一下TCP/IP协议分层及其之间的通信,往后针对每个部分会深入理解,以下仅供参考. 一.TCP/IP与OSI参考模型关系 OSI参考模型注重通信协议必要的功能是什么,而TCP/IP则更强调在计算机上实现协议应该开发哪种程序. 二.TCP/IP协议分层模型各个层次讲解 1. 硬件(物理层) TCP/IP的最底层是负责数据传输的硬件.这种硬件就相当于以太网或电话线路等物理层的设备. 2. 网络接口层(数据链路层) 网络接口层利用以太网中的数据链路层进行通信,因此属于接口层.也就

TCP/IP基础概念及通信过程举例

TCP/IP基础概念及通信过程举例 出现 上个世纪60年代,由于中央集中式网络的容灾性较弱,以美国国防部为中心的一家组织研究出分组交换网络.后来为了验证分组交换技术的实用性,ARPANET出现了,并且在3年内逐渐发展,由4个节点发展至34个节点.20世纪70年代前半叶,ARPANET一个机构研制出了TCP/IP,1982年具体规范确定,1983年成为ARPANET唯一指定协议.乘着TCP/IP的发展之风,互联网应运而生. 标准化 先说明一下TCP/IP的含义.其实它是指利用IP进行通信是所用到的

关于通信的关键词UDP/(TCP/IP)/IPC/RPC/.NET Remoting/WebService/WCF/Http 系列

OSI七层和TCP/IP四层的关系 1.1 OSI引入了服务.接口.协议.分层的概念,TCP/IP借鉴了OSI的这些概念建立TCP/IP模型. 1.2 OSI先有模型,后有协议,先有标准,后进行实践:而TCP/IP则相反,先有协议和应用再提出了模型,且是参照的OSI模型. 1.3 OSI是一种理论下的模型,而TCP/IP已被广泛使用,成为网络互联事实上的标准. TCP:transmission control protocol 传输控制协议 UDP:user data protocol 用户数据