010.第一个回声服务器可能遇到的问题——connect函数
目录
- 由connect函数使用不当导致的小错误
- server.c
- client.c
- 最终效果:
- 新server.c:主要用于排错
- 在回顾connect函数:
- 完整博客:
由connect函数使用不当导致的小错误
博客说明:
在008.一个简单的网络服务器开发----回声服务器篇博客中我们实现了一个最为简单的回声服务器,当时我们为了突出程序的逻辑性,从而没有对部分函数进行错误检查那么博主在这里指出一个大家可能会遇到的一个经典错误,而且这个错误还不是太好排查的,那就是忽略了connect函数的返回值从而导致客户端发了消息但是服务器端并没有回应。
上代码:
server.c
#include<stdio.h>
#include<ctype.h>
#include<unistd.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>#define SERVER_PORT 9527int main(void) {int fd, cfd, n;struct sockaddr_in server_addr, client_addr;socklen_t len_c;char clie_IP[BUFSIZ];char buf[1024];bzero(&server_addr, 0);server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);server_addr.sin_addr.s_addr = htonl(INADDR_ANY);fd = socket(AF_INET, SOCK_STREAM, 0);bind(fd, (struct sockaddr*)&server_addr, sizeof(server_addr));listen(fd, 25);len_c = sizeof(client_addr);cfd = accept(fd, (struct sockaddr*)&client_addr, &len_c);while (1) {n = read(cfd, buf, sizeof(buf));for (int i = 0; i < n; i++) {buf[i] = toupper(buf[i]);}write(cfd, buf, n);write(STDOUT_FILENO, buf, n);}close(cfd);return 0;
}
client.c
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdio.h>
#include<ctype.h>#define SERVER_PORT 9527
#define SERVER_IP "127.0.0.1"
int main(void) {int sfd, n;struct sockaddr_in server_addr;char buf[1024];sfd = socket(AF_INET, SOCK_STREAM, 0);bzero(&server_addr, 0);server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);sfd =connect(sfd, (struct sockaddr*)&server_addr, sizeof(server_addr));while (1) { fgets(buf, sizeof(buf), stdin);write(sfd, buf, strlen(buf));n = read(sfd, buf, sizeof(buf));write(STDOUT_FILENO, buf, n);}close(sfd);return 0;
}
最终效果:
client:可以看出来,并没有实现我们的小写转大写功能。
server:
服务器这端直接什么都没有?可以断定可定是出了什么问题了。那么我么继续去排查。
新server.c:主要用于排错
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>#define SERV_PORT 9527int main(void)
{int sfd, cfd;int len, i;char buf[BUFSIZ], clie_IP[BUFSIZ];struct sockaddr_in serv_addr, clie_addr;socklen_t clie_addr_len;/*创建一个socket 指定IPv4协议族 TCP协议*/sfd = socket(AF_INET, SOCK_STREAM, 0);/*初始化一个地址结构 man 7 ip 查看对应信息*/bzero(&serv_addr, sizeof(serv_addr)); //将整个结构体清零serv_addr.sin_family = AF_INET; //选择协议族为IPv4serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //监听本地所有IP地址serv_addr.sin_port = htons(SERV_PORT); //绑定端口号 /*绑定服务器地址结构*/bind(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));/*设定链接上限,注意此处不阻塞*/listen(sfd, 64); //同一时刻允许向服务器发起链接请求的数量printf("wait for client connect ...\n");/*获取客户端地址结构大小*/ clie_addr_len = sizeof(clie_addr_len);/*参数1是sfd; 参2传出参数, 参3传入传入参数, 全部是client端的参数*/cfd = accept(sfd, (struct sockaddr *)&clie_addr, &clie_addr_len); /*监听客户端链接, 会阻塞*///打印出连接成功的客户端的ip和端口号printf("client IP:%s\tport:%d\n", inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)), ntohs(clie_addr.sin_port));while (1) {/*读取客户端发送数据*/len = read(cfd, buf, sizeof(buf));write(STDOUT_FILENO, buf, len);/*处理客户端数据*/for (i = 0; i < len; i++)buf[i] = toupper(buf[i]);/*处理完数据回写给客户端*/write(cfd, buf, len); }/*关闭链接*/close(sfd);close(cfd);return 0;
}
服务器这端接受的客户端IP为0,也就是根本没有完成和客户端连接,所以客户端得到的是小写也就不足为奇了。
原因剖析:
请大家翻回去看看博主之前写的client.c的代码,write和read可定是没有任何问题的,那么还会有什么地方出问题呢?请仔细思考一下。
在回顾connect函数:
我们再来看看 connet函数吧:
截取部分:
完整博客:
socket编程之 connect()函数
不知道大家是否发现了client.c的问题了?
博主一开始也是着了connect函数的道了,他调用成功之后的返回值居然是0而不是socket描述符。
所以我们可以知道为什么在新编写的server.c中会显示client的ip为0.0.0.0了吧。
就是因为这行代码将本来已经与server连接好的sfd置零了。
删除之后在运行:
client:
server:
所以由此我们需要知道,在做服务器开发的时候我们应该去封装一个专门针对于 bind listen accept connect等函数的出错处理,有了出错处理函数,上述情况的发生是可以大大减小的。
大家能猜到我们第11篇博客的内容了吧,那就是写一个完整的错误处理函数。到时候博主在详细给大家介绍那些功能。
010.第一个回声服务器可能遇到的问题——connect函数相关推荐
- C++回声服务器_3-UDP版本
这次我们实现一个UDP版本的回声服务器. 用于传输数据的函数 UDP套接字不会像TCP套接字那样保持连接状态,因此每次传输数据都要添加目标地址信息. 用于传输数据的函数: 发送数据到目标服务器. #i ...
- Python批量检测服务器端口可用性与Socket函数使用
socket函数 简述 socket又称套间字或者插口,是网络通信中必不可少的工具.有道是:"无socket,不网络".由于socket最早在BSD Unix上使用,而Unix/L ...
- SUN服务器清除所有报错信息,SUN服务器可能遇到的问题总结.doc
SUN服务器可能遇到的问题总结(一)1) Q:现在遇到这样一个问题,telnet一台SUN机时报下面的错误: No utmpx entry. You must exec "login&quo ...
- 012.成型版回声服务器
目录 带错误处理的回声服务器的实现 server.cpp client.cpp error_handling.cpp error_handling.h 遇到的问题,自定义函数显示未定义的引用. 问题分 ...
- 008.一个简单的网络服务器开发----回声服务器
目录 简单的回声服务器实现 项目需求 技术分析 博主相关的技术博客 网络编程之 socket编程 网络编程函数小总结与初识socket 网络编程之bind()的未解之谜 网络编程之 字节序和深入理解b ...
- 基于epoll实现一个IO多路复用的回声服务器
任务: 实现一个TCP server的回声服务器,功能是将客户端发送的消息原样返回,应用epoll处理事件循环实现IO多路复用.借此任务理解IO多路复用应用的开发模式. 参考资料: http://ma ...
- 简单回声服务器的实现
文章目录 1 简单回声服务器的实现 1 简单回声服务器的实现 实现非常非常简单,而且没啥实用价值,代码如下: server.c: #include <stdio.h> #include & ...
- boost::phoenix模块实现自适应回声服务器相关的测试程序
boost::phoenix模块实现自适应回声服务器相关的测试程序 实现功能 C++实现代码 实现功能 boost::phoenix模块实现自适应回声服务器相关的测试程序 C++实现代码 #inclu ...
- [Sharepoint2007对象模型]第一回:服务器场(SPFarm)
Sharepoint是微软一个很重要的服务器产品,它可以方便的创建和维护一个网站,在Sharepoint的管理中心提供了很强大的管理工具.同时为了更加灵活的后期定制和开发,Sharepoint提供了完 ...
最新文章
- vs2012调试中出现char类型形参与LPCTSTR类型不匹配
- filepath直接指定到文件名吗_PyTest运行指定的测试集
- 应用netstat查看目标机TCP连接的状况
- Django基础三之视图函数
- 《深入理解Java虚拟机》第7章 虚拟机类加载机制
- 2022年的PMP考试大纲是什么?
- 备用计算机机房管理制度,计算机机房管理制度
- 工商银行销售基金一览表
- 能不能把ASMR做成一门正经生意?
- 计算机如何理解图像?
- 大数据分析R和RStudio使用指南
- Python pandas 空值缺失值(NaN)处理填充替换判断删除含缺失空值数据行
- 可汉学院python_A可汗学院-统计学python实现1-10
- 论文阅读-VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION
- win10 +anaconda+pytorch_gpu
- 测试CarbonData
- [跟进]_淘宝推出搜索引擎
- iOS 动态表情控件视图的实现
- 表单验证——点击提交后跳转到第一个未通过校验的地方
- PMP管理工具及方法
热门文章
- mysql认证包_mysql协议分析2---认证包
- IntelliJ IDEA 2018 破解 汉化教程地址
- 搞机器学习还敲什么代码
- 腾讯宣布捐赠1亿元驰援河南;苹果回应iPhone 安全隐患;贝索斯完成10分钟太空之旅|极客头条...
- OPPO 40万年薪招应届生,狂揽芯片人才;恶意差评小米新手机,一用户被判赔3万元;谷歌开源全同态加密通用转译器|极客头条...
- Google 和腾讯为什么都采用主干开发模式?
- 一场大火,让云计算巨头的数据中心化为灰烬!10 万Rust 游戏玩家的数据永久丢失,无法恢复
- 国士无双:卖掉美国房子,回国创办姚班,他只为培养一流的程序员!
- 程序员是如何一步一步被诈骗的?《原力计划-打卡挑战》第二周周榜揭晓
- 干货!Python与MySQL数据库的交互实战