利用C语言实现在客户端和服务器端发送一个整数
来源:互联网 发布:建筑公司法务 知乎 编辑:程序博客网 时间:2024/05/21 21:45
tcp的特性就是面向字节流,就是发送的内容必须是字节!如果要发送一个整数的话,由于整数可能是多个字节,所以就需要拆分成多个字节发送,然后发送到服务器端再来进行合并!我这里的实现代码如下:
客户端的代码:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<signal.h>#define SIZE 4096int main(int argc,char *argv[]){ int sockfd; struct sockaddr_in servaddr; char buf_r[SIZE]; char buf_s[SIZE]; memset(&servaddr,0,sizeof(servaddr)); memset(buf_s,0,SIZE); memset(buf_r,0,SIZE); if(argc != 2) {printf("Usage:%s <Server IP address>\n",argv[0]+2);exit(EXIT_FAILURE); } if((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1)//socket第三个参数0表示根据定义的域和类型来自动选择协议 {printf("%s[socket]%s",argv[0]+2,strerror(errno));exit(EXIT_FAILURE); } //给套接字地址结构赋值,用来保存服务器的地址 servaddr.sin_family = AF_INET; servaddr.sin_port = htons(9877); inet_pton(AF_INET,argv[1],(struct in_addr *)&servaddr.sin_addr); //客户端向服务器发起连接请求 if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) == -1) {printf("%s[connect]%s",argv[0]+2,strerror(errno));exit(EXIT_FAILURE); }//********************************************************************************************************// //这里进行数据的处理 int num,loop,count; char c; printf("请输入一个整数:"); while(0 == scanf("%d",&num)) {while((c=getchar()) != EOF); //将缓冲区的内容清空printf("对不起,您输入的数据有误,请重新输入!\n");printf("请输入一个整数:"); } count = (int)(sizeof(int)/sizeof(char)); for(loop=0;loop<count;loop++) {buf_s[loop] = (char)(num >> (loop*sizeof(char)*8)); } printf("Sent:"); for(loop=0;loop<count;loop++)printf("%hhX ",buf_s[count-loop-1]); printf("\n"); write(sockfd,buf_s,strlen(buf_s)); if(read(sockfd,buf_r,SIZE) == 0) {printf("服务器已经关闭了连接!\n");return -1; } else {printf("Receive:");for(loop=0;loop<count;loop++) printf("%hhX ",buf_r[count-loop-1]);printf("\n"); } return 0;}服务器端的代码:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<netinet/in.h>#include<sys/types.h>#include<sys/socket.h>#include<arpa/inet.h>#include<unistd.h>#define SIZE 4096#define CON_SIZE 1024int main(int argc,char *argv[]){ int listenfd,cli_sockfd; struct sockaddr_in servaddr,cliaddr; char buf[SIZE]; //接受缓存 socklen_t len; //接受的客户端的地址结构的长度 char cli_ip[SIZE]; //客户端的IP地址 memset(buf,0,SIZE);/**********************************************************************************************************/ //1.创建监听套接字 if(-1 == (listenfd=socket(AF_INET,SOCK_STREAM,0))) //这里的0表示根据定义的域和协议类型来自动选择协议! {printf("%s[socket]:%s\n",argv[0]+2,strerror(errno));exit(EXIT_FAILURE); }/**********************************************************************************************************/ //2.给服务器地址结构赋值 memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(9877); servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/**********************************************************************************************************/ //3.设置套接字选项,让套接字关闭后地址没有等待时间,能够立刻进行绑定 int on = 1; if(-1 == setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))) {printf("%s[setsockopt]:%s\n",argv[0]+2,strerror(errno));exit(EXIT_FAILURE); }/**********************************************************************************************************/ //4.将服务器地址结构和监听套接字绑定 if(-1 == bind(listenfd,(struct sockaddr *)&servaddr,sizeof(struct sockaddr_in))) {printf("%s[bind]:%s\n",argv[0]+2,strerror(errno));exit(EXIT_FAILURE); }/**********************************************************************************************************/ //5.进行监听 if(-1 == listen(listenfd,CON_SIZE)) {printf("%s[listen]:%s\n",argv[0]+2,strerror(errno));exit(EXIT_FAILURE); } while(1) {/**********************************************************************************************************///6.接受连接请求if(-1 == (cli_sockfd=accept(listenfd,(struct sockaddr*)&cliaddr,&len))){ printf("%s[accept]:%s\n",argv[0]+2,strerror(errno)); exit(EXIT_FAILURE);}if(NULL == inet_ntop(AF_INET,&cliaddr.sin_addr,cli_ip,SIZE)) //保存发送端的IP地址{ printf("%s[inet_ntop]:%s\n",argv[0]+2,strerror(errno)); exit(EXIT_FAILURE);}ntohs(cliaddr.sin_port);//保存发送端的端口号printf("[%s:%d]连接已建立\n",cli_ip,cliaddr.sin_port);/**********************************************************************************************************///7.接受并回传数据int loop;int num,num_temp;if(-1 == read(cli_sockfd,buf,SIZE)){ printf("%s[read]:%s\n",argv[0]+2,strerror(errno)); exit(EXIT_FAILURE);}for(loop=0;loop<4;loop++){ num_temp = (int)buf[4-loop-1]; num_temp = num_temp << ((4-loop-1)*8); switch(4-loop-1) { case 0:num_temp = num_temp | 0xFFFFFF00;num = num & num_temp;break; case 1:num_temp = num_temp | 0xFFFF00FF;num = num & num_temp;break; case 2:num_temp = num_temp | 0xFF00FFFF;num = num & num_temp;break; case 3:num_temp = num_temp | 0x00FFFFFF;num = num_temp;break; } printf("%hhX ",buf[4-loop-1]);}printf("\n");printf("发送过来的数是:%d\n",num);if(-1 == write(cli_sockfd,buf,strlen(buf))){ printf("%s[write]:%s\n",argv[0]+2,strerror(errno)); exit(EXIT_FAILURE);}/**********************************************************************************************************///8.关闭套接字if(-1 == close(cli_sockfd)){ printf("%s[close]:%s\n",argv[0]+2,strerror(errno)); exit(EXIT_FAILURE);}else{ printf("[%s:%d]创建的套接字已经关闭\n",cli_ip,cliaddr.sin_port); memset(buf,0,SIZE);} } return 0;}
这个程序实现的比较简单,就是客户端发送一个整数给服务器端,然后服务器端显示这个整数是多少,再把这个字节流回传给客户端!运行结果如下图:
程序的不足之处:
1.整数的长度问题:
我这里用的是int类型,在客户端可以通过sizeof获取到要发送到整数的长度,但是在服务器端我还没想好怎样来传送整数的长度比较好,所以直接用了一个4!并没有实现判断整数到底是多少个字节!
2.字节序问题:
在不同的主机上,可能是大端字节序或者是小端字节序,我这里并没有做处理,因为我这里是用127.0.0.1来实验的,都是在我的电脑上,所以字节序是相同的!我这里不知道的是如何获取一个一个主机的字节序,所以这里还没做!
0 0
- 利用C语言实现在客户端和服务器端发送一个整数
- socket用线程实现客户端和服务器端连续发送数据
- 利用c语言实现在一个3*3棋盘游戏
- axis利用wsdl生成webservice服务器端和客户端代码实现
- {网络编程}和{多线程}应用:基于TCP协议【实现多个客户端发送文件给一个服务器端】--练习
- 利用TCP从客户端往服务器端发送一个文件过程中发生的问题
- 【C语言】利用kill函数实现一个进程向另一个进程发送信号
- 服务器端和android客户端通信 服务器端实现
- 利用socket实现客户端与服务器端聊天
- 利用rmi实现客户端与服务器端通信
- 嵌入式 C语言实现在0x1000地址处写入一个单字节的整数
- 在客户端(js)调用服务器端方法(C#)
- 服务器端和客户端不同类型语言编译问题
- c语言实现将一个整数转换为字符串
- 获取一个整数所有的质因数(C语言实现)
- C语言实现:查找一个整数中1的个数
- 利用Struts的Validator验证框架实现客户端和服务器端双验证
- 利用Struts的Validator验证框架实现客户端和服务器端双验证
- Unity碰撞盒光源声效及树木制作
- Hibernate框架(二)POJO对象的操作
- leetcode Combinations
- MySQL常用函数
- 静态库和动态库
- 利用C语言实现在客户端和服务器端发送一个整数
- Network Connections UVA 793(并查集)
- 第11周项目2.2 四个数的最大公约数
- UVa 10976 - Fractions Again?!
- sqlplus 列设置与报表应用
- Hibernate框架(三)框架中的关系映射
- leetcode Combination Sum
- 《网蜂A8实战演练》——9.Linux NAND FLASH 驱动
- 【iOS】iOS点击键盘以外空白区域隐藏键盘的常见方法