初探网络编程

网络编程是Linux开发中的重要部分,Linux环境网络编程是基于Socket的C语言编程,Socket本意是插座,它在网络中描述不同计算机之间通信的方式。网络通信中可以使用TCP或者UDP协议,对于我们来说不会太关心协议本身的细节,而是更关注不同主机之间传输的过程,因此制定了一种用于网络传输数据的编程接口,称为套接字(Socket)。

Socket编程接口内容很多,我自己看了一部分之后感觉学习过程中需要分析数据通信的过程,理解网络中的基础知识才不至于混肴。下面是一些网络编程的基本操作。

1、网络编程的基本概念

  1. IP地址
    网络中的计算机均有唯一IP地址,用来标识它在网路中的身份,我们常见的就是点分十进制写法的IP地址,如“210.187.77.10”。实际上在通信过程中IP地址是以整型方式存储的,如“193921391”。我们看到的点分十进制IP地址是由网络整型IP转为点分IP字符串得到的。
  2. 端口 网络中的端口不同于硬件中的端口,IP地址标识了网络世界的主机,端口号指明了主机中的具体网络程序,比如FTP端口号是21,端口范围是0~65535,低于256的是系统保留端口。
  3. 域名 域名是用来代替IP地址来直观标识计算机的直观名称,如百度IP http://www.baidu.com. ping www.baidu.com 表明域名指向的IP地址是202.108.22.43.
  4. TCP/UDP
    TCP与UDP是两种不同的网络传输方式,使用IP和Port,要使用一种约定方式进行数据传输,TCP/UDP就是网络中两种数据传输约定,主要区别是数据传输时是否进行连接。

2、套接字

区别不同应用程序进程间通信和连接,只要使用三个参数:通信的目的IP,使用的传输层协议(TCP/IP)和端口号,编程时这三个参数构成一个套接字接口。

C程序进行套接字编程时,使用sockaddr_in数据类型,这是系统定义的结构体,用于保存套接字信息,定义如下:

struct socketaddr
{
    usigned short int sin_family;
    uint16_t sin_port;
    struct in_addr sin_addr;
    unsigned char sin_zero[8];
}
  • sin_family:指定通信的地址类型,如果是TCP/IP通信,该值为AF_INET
  • sin_port:套接字使用的端口号。
  • sin_addr:要访问的IP地址。
  • sin_zero:未使用的字段,填充为0。

套接字的类型

  • 流套接字(SOCK_STREAM)
    面向连接的可靠数据通信方式,即TCP协议;
  • 数据报套接字(SOCK_DGRAM) 面向无连接的数据通信方式,即UDP协议;
  • 原始套接字(SOCK_RAW) 前面两种是系统定义的,所有信息都要按照这种方式金星封装,原始套接是没有经过处理的IP数据包,可以按照自己程序的要求进行封装。

3、域名与IP

域名取得相对应的IP地址
struct hostent *gethostbyname(const char *name);
name是保存域名的字符串,函数返回指向hostent结构体的指针,hostent结构体定义如下:

struct hostent
{
    char *h_name;
    char **h_aliases;
    int h_addrtype;
    int h_length;
    char **h_addr_list;
}

h_name 主机名称
h_aliases 主机别名
h_addrtype 主机名类型
h_length 地址长度
h_addr_list 主机IP

IP取得相对应的域名
struct hostent *gethostbyaddr(const void *addr,socklen_t len,int type);
参数列表中addr是保存IP地址的字符串,len是IP地址长度,type一般为AF_INET

4、网络协议

网络协议是指不同计算机之间进行通信的约定,在进行网络编程时需要遵循这些协议。

  • 由协议名取得协议数据
    struct protoent *getprotobyname(char *name);
    name是一个协议名称字符串,返回一个protoent结构体指针,protoent定义如下:
struct protoent
{
    char *p_name;
    char **p_aliases;
    int p_proto;
}

p_name:协议的名称
p_aliases:协议的别名
p_proto:协议的序号
struct protoent *pro=getprotobyname(“tcp”);

  • 由协议编号取得协议数据
    struct protoent *pro=getprotobynumber(“tcp”);
  • 获得系统支持的所有协议
    struct protoent *pro
while(pro=getprotoent())
{
    ...
}

5、网络服务

所谓网络服务,指的是网络上的计算机通过运行程序,为其他计算机提供信息或运算的功能。

  • 函数getserent的作用是获取系统所支持的服务,getservent函数定义如下
    struct servent *getservent(void);
    servent结构体如下
struct servent
{
    char *s_name;
    char **s_aliases;
    int s_port;
    char *s_proto;
}

s_name:服务名
s_aliases:服务别名
s_port:服务端口号
s_proto:服务使用的协议

  • 服务名称获取服务
    struct servent *getservbyname(char *name,char *proto);
  • 端口取得服务名称
    struct servent *getservbyport(int port,char *proto);

6、网络地址的转换

网络地址本是用32位二进制数来表示的,为了记忆方便,可以用点分十进制数来表示IP地址。同时,网络传输与计算机内部的字符存储方式是不同的,需要相关函数将端口号进行转换。

  • 网络地址转换为整型
    函数inet_addr可以将网络IP转为十进制长整型数。
    long inet_addr(char *cp);
    参数cp是一个IP地址字符串,使用这个函数前需要包含头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
  • 长整型地址转为网络地址
    函数inet_ntoa可以将整形地址转为网络地址,进而转换为点分十进制地址。
    char *inet_ntoa(struct in_addr in);
    使用实例:
struct in_addr ip;
ip.s_addr=16885952;
printf("%s",inet_ntoa(ip));
  • 主机字符顺序与网络字符顺序的转换
    计算机中的整型与网络中的整型进行交换时,需要相关的函数进行交换。这些函数如下
uint32_t htonl(uint32_t hostlong)
uint16_t htons(uint16_t hostshort)
uint32_t ntohl(uint32_t netlong)
uint16_t ntohs(uint16_t netshort)

7、错误处理

  • herror函数显示错误
    函数herror可以显示上一个网络函数发生的错误,定义如下
    void herror(const char *s);
    函数参数是字符串,调用函数是首先输出字符串信息,然后输出错误信息
char s[]="error:";
herror(s);
  • 捕获错误编号
    网络程序中使用下面的语句来捕获错误编号:
    extern int h_errno;
    捕获到错误编号后,可以用hstrerror函数输出错误信息
char *hstrerror(int err)   //err是上面捕获的错误编号h_errno

以上是socket编程的基础知识!

时间: 2024-10-12 10:49:05

初探网络编程的相关文章

head first c&lt;11&gt;初探网络编程上

服务器连接网络四部曲. 为了与外界沟通,c程序用数据流读写字节,比较常用的数据流有标准输入.标准输出.文件等. 如果想写一个与网络通信的程序,就需要一种新的数据流----------套接字. 使用套接字与客户端程序通信前,服务器需要历经四个阶段:绑定.监听.接受.开始. 1.绑定端口 计算机可能同时运行多个服务器程序,为了放置不同的对话混淆,每项服务必须使用不同的端口(port).端口就好像电视频道, 用不同的频道接受不同的节目. 服务器在启动时,需要告诉操作系统将要使用哪个端口,这个过程叫端口

head first c&lt;11&gt;初探网络编程下

上一篇博文可以实现基本的网络通信,但是只能服务给一个人,我们可以通过给每个客户端fork()一个子进程,来实现一对多的服务. 方法: 客户端连到服务器以后,服务器启动一个新创建的套接字对话,也就是说父进程可以继续连接下一个客户端,而子进程来需要处理 accept()创建的副套接字,实现通信功能.父进程克隆子进程后可以关闭副套接字close(connect_d),而子进程可以关闭主监听套接 字close(listener_d). 说了半天就是,一个只负责拉客,一个只负责接客. while(1) {

head first c&amp;lt;11&amp;gt;初探网络编程上

server连接网络四部曲. 为了与外界沟通,c程序用数据流读写字节.比較经常使用的数据流有标准输入.标准输出.文件等. 假设想写一个与网络通信的程序.就须要一种新的数据流----------套接字. 使用套接字与client程序通信前,server须要历经四个阶段:绑定.监听.接受.開始. 1.绑定port 计算机可能同一时候执行多个server程序.为了放置不同的对话混淆.每项服务必须使用不同的port(port).port就好像电视频道, 用不同的频道接受不同的节目. server在启动时

Socket网络编程初探

MarkdownPad Document Socket网络编程初探 客户端/服务器架构 即C/S架构,其实web服务在某种意义上也算是C/S架构 一个特点是服务器端持续运行对外提供服务 为何学习socket一定要先学习互联网协议: C/S架构的软件是基于网络进行通信的 网络的核心就是一堆协议,即标准,想要开发一款基于网络通信的软件就必须遵循这些标准 socket是处在应用层和传输层中间的一组接口 说到这,那么socket到底是个什么呢?Socket是应用层与TCP/IP协议族通信的中间软件抽象层

2015/12/14 Python网络编程,TCP/IP客户端和服务器初探

一直不是很清楚服务器的定义,对于什么是服务器/客户端架构也只有一个模糊的感觉.最近开始学习,才明白一些什么服务器和客户端的关系. 所谓的服务器,就是提供服务的东西,它是一个硬件或者软件,可以向一个或者多个客户端提供所需要的服务.它存在的目的就是等待客户的请求,然后给客户服务,再接着等待请求. 而客户端,就来连上一个服务器,提出自己的请求,然后等待获得反馈. 比如说,打印机就是一个服务器的例子,与之相连的计算机就是客户端,通过网络连接打印机后,给它提出服务需求(打印)和传输数据(传输内容),然后打

网络编程(3)——初探HTTP协议

背景 我们在网络编程(1)中知道:计算机之间的通信可以利用URL手段来定位资源.这种手段是基于TCP/IP协议族来实现的. 所谓基于TCP/IP协议族,其实(1)中获取网络资源定位来理解比较好,从IP和端口来理解: IP协议是计算机用来相互识别的通信的一种机制,每台计算机都有一个IP.用来在因特网上标识这台计算机.IP协议仅仅是允许计算机相互发消息,但它并不检查消息是否以发送的次序到达而且没有损坏(只检查关键的头数据).为了提供消息检验功能,直接在IP协议上设计了传输控制协议TCP协议. TCP

Linux C 网络编程之初探

下面的一幅图是取自<UNIX网络编程卷一>,这个简单的C/S程序的框架 Service端程序 #include <stdlib.h> #include <sys/types.h> #include <stdio.h> #include <sys/socket.h> #include <linux/in.h> #include <string.h> int main() { int sfp,nfp; /* 定义两个描述符 *

Java 网络编程初探

Java 网络编程 网络编程 网络编程:进行服务器端与客户端编程的开发操作实现. java.net:网络操作包 B/S结构: 浏览器/服务器模式(Browser/Server) 不在开发客户端代码 开发一套服务器端的程序代码 客户端利用浏览器进行访问 维护方便,安全性能低(使用公共的HTTP协议和80端口) C/S结构: 客户端/服务器模式(Client / Server) 需要编写两套程序: 客户端程序代码 服务器程序代码 C/S的开发非常的繁琐,因为开发人员需要维护两套程序.(运维哭) 优点

Python网络编程—socket(一)

从今天开始python基础就介绍完毕了,下面我们将进阶到socket网络编程的介绍,那么socket是什么呢?我们带着这个问题开始今天的介绍: 一.socket初探 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket其实也是一种特殊的文件,一些socket函数就是对其进行的操作(读/写.打开.关闭) 那么socket对文件操作和file对文件操作有什么区别呢? fil