最近在学习Linux网络编程方面的知识,感觉还是有些困难。主要是对协议过程的理解,还有socket的API的理解不够深刻。今天复习编写了一个TCP的服务端和客户端的程序实现client.c从命令行参数中获得一个字符串发给服务器,然后接收服务器返回的已处理的字符串并打印。

  

  server.c

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> #define MAXLINE 80
#define SERV_PORT 8000 int main(void)
{
struct sockaddr_in servaddr,cliaddr; //IPV4的地址结构
socklen_t cliaddr_len;
int listenfd,connfd;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
int i,n; if(- == (listenfd = socket(AF_INET,SOCK_STREAM,))) //对于IPV4的family的参数为AF_INET for TCP SOCK_STREAM 表示面向流的传输协议
{
perror("socket Error");
exit();
}
bzero(&servaddr,sizeof(servaddr)); //对于UDP协议 type is SOCK_DGRAM 表示面向数据报的传输协议 protocol指定为零
servaddr.sin_family = AF_INET; //设置地址类型
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//网络地址为INADDR_ANY
servaddr.sin_port = htons(SERV_PORT); //端口号为SERV_PORT 定义为8000 if(- == bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)))
{
perror("Bind error");
exit();
} if( - == listen(listenfd,))
{
perror("Listen error");
exit();
} printf("Accepting connections ..\n"); while(){
cliaddr_len = sizeof(struct sockaddr_in);
if( - == (connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&cliaddr_len)))
{
perror("Accept error");
exit();
} if(- ==(n = read(connfd,buf,MAXLINE)))
{
perror("read error");
exit();
}
printf("Connect from %s:%u ...!\n",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port)); for (i = ; i < n; i++)
buf[i] = toupper(buf[i]);
write(connfd, buf, n); close(connfd);
}
close(listenfd);
exit();
}

  client.c

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h> #define MAXLINE 80
#define SERV_PORT 8000 int main(int argc,char **argv)
{
struct sockaddr_in servaddr;
char buf[MAXLINE];
int sockfd,n;
char *str; if(argc != )
{
fputs("Usage: ./client message\n",stderr);
exit();
}
str = argv[];
sockfd = socket(AF_INET,SOCK_STREAM,);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT); connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
write(sockfd,str,strlen(str));
n = read(sockfd,buf,MAXLINE);
printf("Response from server:\n"); //if(-1 == read(sockfd,buf,1024)){
// perror("Recv Error:");
//}
write(STDOUT_FILENO, buf, n); close(sockfd);
return ;
}

  但是发现一直有个Segmentation fault显示没有返回正确的结果,一开始还以为是数组buf越界了,但检查总是没有什么问题。

[root@VM_62_27_centos changeBigSmall]# ./server
Accepting connections ..
Segmentation fault

[root@VM_62_27_centos changeBigSmall]# ./client abcdef
Response from server:
[root@VM_62_27_centos changeBigSmall]#

  发现也没有出现perror()的错误还有printf一直没有打印连接的端口号,连接成功理应由成功连接的地址端口显示出来。最后对函数inet_ntoa()查询是发现要加入<arpa/inet.h> 的头文件。哦NO,原来没有加入相应的头文件也会引起段错误。

  加上就好了<arpa/inet.h>的头文件就好了

[root@VM_62_27_centos changeBigSmall]# ./client abcd
Response from server:
ABCD[root@VM_62_27_centos changeBigSmall]#

  那经过此次教训之后,还是总结一下网络编程中常见的头文件。

 sys/types.h:数据类型定义

 sys/socket.h:提供socket函数及数据结构

 netinet/in.h:定义数据结构sockaddr_in

 arpa/inet.h:提供IP地址转换函数

 netdb.h:提供设置及获取域名的函数

 sys/ioctl.h:提供对I/O控制的函数

 sys/poll.h:提供socket等待测试机制的函数

  其他常见的头文件

unistd.h:提供通用的文件、目录、程序及进程操作的函数

errno.h:提供错误号errno的定义,用于错误处理

fcntl.h:提供对文件控制的函数

time.h:提供有关时间的函数

crypt.h:提供使用DES加密算法的加密函数

pwd.h:提供对/etc/passwd文件访问的函数

shadow.h:提供对/etc/shadow文件访问的函数

pthread.h:提供多线程操作的函数

signal.h:提供对信号操作的函数

sys/wait.h、sys/ipc.h、sys/shm.h:提供进程等待、进程间通讯(IPC)及共享内存的函数

  还有一些常见的结构体

struct sockadd {
unsigned short sa_family;
char sa_data[];
} struct sockaddr_in {
short int sin_family; //AF_INET
unsigned short int sin_port; //网络字节顺序
struct in_addr sin_addr; //struct in_addr { unsigned long s_addr; }
unsigned char sin_zero[];
}

  

  

arpa/inet.h所引起的Segmentation fault及网络编程常见的头文件的更多相关文章

  1. Linux程序Segmentation fault (core dumped)

    1 问题原因 Segmentation fault (core dumped)多为内存不当操作造成.空指针.野指针的读写操作,数组越界访问,破坏常量等.对每个指针声明后进行初始化为NULL是避免这个问 ...

  2. 《UNIX网络编程(第3版)》unp.h等源码文件的编译安装

    操作系统:Mac OS X 10.11.5 1.下载书中的源代码:点击下载 2.切换到解压后的目录 unpv13e,先查看下 README,依次执行: ./configure cd lib make ...

  3. 常用的头文件—— common.h

    #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/sta ...

  4. 头文件intrins.h

    intrins.h 在C51单片机编程中,头文件INTRINS.H的函数使用起来,就会让你像在用汇编时一样简便. 内部函数 描述 _crol_ 字符循环左移   _cror_ 字符循环右移   _ir ...

  5. C语言中你可能不熟悉的头文件(stdlib.h)

    C语言中你可能不熟悉的头文件<cstdlib>(stdlib.h) C Standard General Utilities Library (header) C标准通用工具库(头文件) ...

  6. 万能头文件#include <bits/stdc++.h>

    最近在做题的时候看到别人的题解发现别人都用这个 突然之间打开新世界的大门 去百度之后才知道#include <bits/stdc++.h>包含了目前所有的c++头文件 也就是说只要用#in ...

  7. Visual Studio中头文件stdafx.h的作用

    在较新版的Visual Studio中,新生成的C++项目文件的的头文件夹下会默认有头文件stdafx.h,而源文件夹下则默认有源文件stdafx.cpp,手动将这些文件删除后,编译时系统还会报错.下 ...

  8. 头文件string.h,cstring与string

    string.h string.h是一个C标准头文件,所有的C标准头文件都形如name.h的形式,通过#include <string.h>可以导入此头文件.之后我们就可以在程序中使用st ...

  9. Linux下的段错误(Segmentation fault)

    Linux开发中常见段错误问题原因分析 1 使用非法的内存地址(指针),包括使用未经初始化及已经释放的指针.不存在的地址.受系统保护的地址,只读的地址等,这一类也是最常见和最好解决的段错误问题,使用G ...

随机推荐

  1. R语言hist绘图函数

    hist 用于绘制直方图,下面介绍每个参数的作用: 1)x: 用于绘制直方图的数据,该参数的值为一个向量 代码示例: data <- c(rep(1, 10), rep(2, 5), rep(3 ...

  2. vsearch 去除重复序列和singleton 序列

    在16S数据分析中,为了减少聚类的时间,提高准确度,需要去除重复序列,而singleton序列因为没有其他的序列作为验证,可信度不是很高,也需要去除,通常情况下使用usearch 完成这2项任务,但是 ...

  3. 教您如何在Word的mathtype加载项中修改章节号

    在MathType数学公式编辑器中,公式编号共有五部分内容:分别是章编号(Chapter Number).节编号(Section Number).公式编号(Equation Number).括号(En ...

  4. oracle_存储过程_没有参数_更新过期申请单以及写日志事务回滚

    CREATE OR REPLACE PROCEDURE A_MEAS_MIINSP_PLAN_UPDATEASvs_msg VARCHAR2(4000);log_body VARCHAR2(400); ...

  5. 09python之运算

    运算 算数运算: 两个数相除,得到商和余数的数组的内置方法  数据.__divmod__()  场景 数据库共99条数据,每个页面10条数据,需要多少个页面  >>> a = 98  ...

  6. 【渗透测试学习平台】 web for pentester -8.XML

    example1: http://192.168.91.139/xml/example1.php?xml=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%2 ...

  7. 设置jQuery validate插件错误提示位置

    参照上一篇bootstrap布局注册表单 使用校验插件默认位置显示提示信息,发现错误提示信息换行了,由于增加了提示信息,表单显示高度也增加了,如下 默认提示信息位置代码为 将错误提示设置其显示在右边, ...

  8. 对double数据类型的数据保留两位小数,并且进行四舍五入

    1.代码如下: /** * 对double数据类型的数据 保留两位小数,并且进行四舍五入 * @author Administrator */ public class Main { // 工具类 p ...

  9. ZooKeeper(七)-- ZK原生API实现分布式锁

    一.使用场景 在分布式应用,往往存在多个进程提供同一服务.这些进程有可能在相同的机器上,也有可能分布在不同的机器上. 如果这些进程共享了一些资源,可能就需要分布式锁来锁定对这些资源的访问. 二.实现分 ...

  10. Qt监控Access数据库

    配置文件setup.ini内容 [General] DBFilePath=C:/Users/WangGang/Desktop/Database1.accdb DBUserName= DBPasswor ...