linux 网络编程常用函数及流程

一、网络编程之TCP流程

服务端:socket---bind---listen---while(1){---accept---recv---send---close---}---close

客户端:socket----------------------------------connect---send---recv-----------------close

二、网络编程常用函数

服务器端:

  1. 头文件包含:

#include<sys/types.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include<unistd.h>

#include<string.h>

#include <stdio.h>

#include <stdlib.h>

2. socket函数:生成一个套接口描述符。

原型:int socket(int domain,int type,int protocol);

参数:domain->{ AF_INET:Ipv4网络协议AF_INET6:IPv6网络协议}

type->{tcp:SOCK_STREAM   udp:SOCK_DGRAM}

protocol->指定socket所使用的传输协议编号。通常为0.

返回值:成功则返回套接口描述符,失败返回-1。

常用实例:int sfd = socket(AF_INET, SOCK_STREAM, 0);

if(sfd == -1){perror("socket");exit(-1);}

3. bind函数:用来绑定一个端口号和IP地址,使套接口与指定的端口号和IP地址相关联。

原型:int bind(int sockfd,struct sockaddr * my_addr,int addrlen);

参数:sockfd->为前面socket的返回值。

my_addr->为结构体指针变量

对于不同的socket domain定义了一个通用的数据结构
struct sockaddr  //此结构体不常用
{
unsigned short int sa_family;  //调用socket()时的domain参数,即AF_INET值。
char sa_data[14];  //最多使用14个字符长度
};
此sockaddr结构会因使用不同的socket domain而有不同结构定义,
例如使用AF_INET domain,其socketaddr结构定义便为
struct sockaddr_in  //常用的结构体
{
unsigned short int sin_family;  //即为sa_family èAF_INET
uint16_t sin_port;  //为使用的port编号
struct in_addr sin_addr;  //为IP 地址
unsigned char sin_zero[8];  //未使用
};
struct in_addr
{
uint32_t s_addr;
};
addrlen->sockaddr的结构体长度。通常是计算sizeof(struct sockaddr);

返回值:成功则返回0,失败返回-1

常用实例:struct sockaddr_in my_addr;  //定义结构体变量

memset(&my_addr, 0, sizeof(struct sockaddr)); //将结构体清空

//或bzero(&my_addr, sizeof(struct sockaddr));

my_addr.sin_family = AF_INET;  //表示采用Ipv4网络协议

my_addr.sin_port = htons(8888);  //表示端口号为8888,通常是大于1024的一个值。

      //htons()用来将参数指定的16位hostshort转换成网络字符顺序

my_addr.sin_addr.s_addr = inet_addr("192.168.0.101"); //inet_addr()用来将IP地址字符串转换成网络所使用的二进制数字,如果为INADDR_ANY,这表示服务器自动填充本机IP地址。

if(bind(sfd, (struct sockaddr*)&my_str, sizeof(struct socketaddr)) == -1)

{perror("bind");close(sfd);exit(-1);}

(注:通过将my_addr.sin_port置为0,函数会自动为你选择一个未占用的端口来使用。同样,通过将my_addr.sin_addr.s_addr置为INADDR_ANY,系统会自动填入本机IP地址。)

4. listen函数:使服务器的这个端口和IP处于监听状态,等待网络中某一客户机的连接请求。如果客户端有连接请求,端口就会接受这个连接。

原型:int listen(int sockfd,int backlog);

参数:sockfd->为前面socket的返回值.即sfd

backlog->指定同时能处理的最大连接要求,通常为10或者5。最大值可设至128

返回值:成功则返回0,失败返回-1

常用实例:if(listen(sfd, 10) == -1)

{perror("listen");close(sfd);exit(-1);}

5. accept函数:接受远程计算机的连接请求,建立起与客户机之间的通信连接。服务器处于监听状态时,如果某时刻获得客户机的连接请求,此时并不是立即处理这个请求,而是将这个请求放在等待队列中,当系统空闲时再处理客户机的连接请求。当accept函数接受一个连接时,会返回一个新的socket标识符,以后的数据传输和读取就要通过这个新的socket编号来处理,原来参数中的socket也可以继续使用,继续监听其它客户机的连接请求。(也就是说,类似于移动营业厅,如果有客户打电话给10086,此时服务器就会请求连接,处理一些事务之后,就通知一个话务员接听客户的电话,也就是说,后面的所有操作,此时已经于服务器没有关系,而是话务员跟客户的交流。对应过来,客户请求连接我们的服务器,我们服务器先做了一些绑定和监听等等操作之后,如果允许连接,则调用accept函数产生一个新的套接字,然后用这个新的套接字跟我们的客户进行收发数据。也就是说,服务器跟一个客户端连接成功,会有两个套接字。)

原型:int accept(int s,struct sockaddr * addr,int * addrlen);

参数:s->为前面socket的返回值.即sfd

addr->为结构体指针变量,和bind的结构体是同种类型的,系统会把远程主机的信息(远程主机的地址和端口号信息)保存到这个指针所指的结构体中。

addrlen->表示结构体的长度,为整型指针

返回值:成功则返回新的socket处理代码new_fd,失败返回-1

常用实例:struct sockaddr_in clientaddr;

memset(&clientaddr, 0, sizeof(struct sockaddr));

int addrlen = sizeof(struct sockaddr);

int new_fd = accept(sfd, (struct sockaddr*)&clientaddr, &addrlen);

if(new_fd == -1)

{perror("accept");close(sfd);exit(-1);}

printf("%s %d success connect\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));

6. recv函数:用新的套接字来接收远端主机传来的数据,并把数据存到由参数buf 指向的内存空间

原型:int recv(int sockfd,void *buf,int len,unsigned int flags);

参数:sockfd->为前面accept的返回值.即new_fd,也就是新的套接字。

buf->表示缓冲区

len->表示缓冲区的长度

flags->通常为0

返回值:成功则返回实际接收到的字符数,可能会少于你所指定的接收长度。失败返回-1

常用实例:char buf[512] = {0};

if(recv(new_fd, buf, sizeof(buf), 0) == -1)

{perror("recv");close(new_fd);close(sfd);exit(-1);}

puts(buf);

7. send函数:用新的套接字发送数据给指定的远端主机

原型:int send(int s,const void * msg,int len,unsigned int flags);

参数:s->为前面accept的返回值.即new_fd

msg->一般为常量字符串

len->表示长度

flags->通常为0

返回值:成功则返回实际传送出去的字符数,可能会少于你所指定的发送长度。失败返回-1

常用实例:if(send(new_fd, "hello", 6, 0) == -1)

{perror("send");close(new_fd);close(sfd);exit(-1);}

8. close函数:当使用完文件后若已不再需要则可使用close()关闭该文件,并且close()会让数据写回磁盘,并释放该文件所占用的资源

原型:int close(int fd);

参数:fd->为前面的sfd,new_fd

返回值:若文件顺利关闭则返回0,发生错误时返回-1

常用实例:close(new_fd);

close(sfd);

客户端:

1. connect函数:用来请求连接远程服务器,将参数sockfd 的socket 连至参数serv_addr 指定的服务器IP和端口号上去。

原型:int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);

参数:sockfd->为前面socket的返回值,即sfd

serv_addr->为结构体指针变量,存储着远程服务器的IP与端口号信息。

addrlen->表示结构体变量的长度

返回值:成功则返回0,失败返回-1

常用实例:struct sockaddr_in seraddr;//请求连接服务器

memset(&seraddr, 0, sizeof(struct sockaddr));

seraddr.sin_family = AF_INET;

seraddr.sin_port = htons(8888); //服务器的端口号

seraddr.sin_addr.s_addr = inet_addr("192.168.0.101");  //服务器的ip

if(connect(sfd, (struct sockaddr*)&seraddr, sizeof(struct sockaddr)) == -1)

{perror("connect");close(sfd);exit(-1);}

时间: 2024-09-30 13:03:42

linux 网络编程常用函数及流程的相关文章

linux socket网络编程 常用函数及头文件

转自:http://blog.chinaunix.net/u3/102500/showart_2065640.html 一 三种类型的套接字: 1.流式套接字(SOCKET_STREAM) 提供面向连接的可靠的数据传输服务.数据被看作是字节流,无长度限制.例如FTP协议就采用这种. 2.数据报式套接字(SOCKET_DGRAM) 提供无连接的数据传输服务,不保证可靠性. 3.原始式套接字(SOCKET_RAW) 该接口允许对较低层次协议,如IP,ICMP直接访问. 二 基本套接字系统调有有如下一

linux网络编程常用头文件

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的定义,用于错误处理

Linux网络编程-readn函数实现

readn函数功能:在网络编程的读取数据中,通常会需要用到一个读指定字节才返回的函数,linux系统调用中没有给出,需要自己封装. readn实现代码: int readn(int fd, void *vptr, size_t n) { size_t nleft = n; //readn函数还需要读的字节数 ssize_t nread = 0; //read函数读到的字节数 unsigned char *ptr = (char *)vptr; //指向缓冲区的指针 while (nleft >

Linux网络编程--IO函数以及示例

网络数据能够正确到达用户并被用户接收是进行网络数据传输的基本目的, 网络数据的接受和发送有很多种方案,例如:直接发送和接收,通过向量发送和接收,使用消息发送和接收等.本篇文章主要介绍常用的IO函数以及用法,如:最常用的read()/write()函数,和其他标准的套接字专用函数recv()/send(),readv()/writev(),recvmsg()/sendmsg(). 各个函数原型以及介绍如下: ssize_t read(int fd, void *buf, size_t count)

Linux网络编程---htons函数的使用

htons是将整型变量从主机字节顺序转变成网络字节顺序, 就是整数在地址空间存储方式变为高位字节存放在内存的低地址处. htonl就是把本机字节顺序转化为网络字节顺序所谓网络字节顺序(大尾顺序)就是指一个数在内存中存储的时候"高对低,低对高"(即一个数的高位字节存放于低地址单元,低位字节存放在高地址单元中).但是计算机的内存存储数据时有可能是大尾顺序或者小尾顺序.先举个例子:int a = 0x403214;int b = htonl(a);我在VC++6.0调试这段代码,发现&

Linux网络编程函数

转自:http://blog.csdn.net/hrbeuwhw/article/details/8050911 1.字节序函数 #include<netinet.h> uint16_t htons(uint16_t host16bitvalue); uint32_t htonl(uint32_t host32bitvalue); 返回:网络字节序值 uint16_t ntohs(uint16_t net16bitvalue); uint32_t ntohl(uint32_t net32bit

linux网络编程九:splice函数,高效的零拷贝

from:http://blog.csdn.net/jasonliuvip/article/details/22600569 linux网络编程九:splice函数,高效的零拷贝 最近在看<Linux高性能服务器编程>,在此做个日记,以激励自己,同时分享于有需要的朋友. 1. splice函数 [cpp] view plain copy #include <fcntl.h> ssize_t splice(int fd_in, loff_t *off_in, int fd_out, 

Linux网络编程:客户端/服务器的简单实现

一. Socket的基本知识 1. socket功能 Socket层次 Socket实质上提供了进程通信的端点,进程通信之前,双方必须首先各自创建一个端点,否则是没有办法建立联系并相互通信的. 每一个Socket都一个半相关描述: {协议, 本地地址, 本地端口} 完整的Socket的描述: {协议, 本地地址, 本地端口, 远程地址, 远程端口} 2. Socket工作流程 面向连接(TCP)的Socket工作流程 UDP的socket工作流程 l 服务器端 首先,服务器应用程序用系统调用so

嵌入式 Linux网络编程(一)——Socket网络编程基础

嵌入式 Linux网络编程一--Socket网络编程基础 一.Socket简介 1.网络中进程间通信 本机进程使用进程号区别不同的进程进程间通信方式有管道.信号.消息队列.共享内存.信号量等.网络中进程间的通信首先需要识别进程所在主机在网络中的唯一标识即网络层的IP地址主机上的进程可以通过传输层的协议与端口号识别. 2.Socket原理 Socket是应用层与TCP/IP协议族通信的中间软件抽象层是一种编程接口.Socket屏蔽了不同网络协议的差异支持面向连接(Transmission Cont