linux 网络编程 socket编程
- 格式:pdf
- 大小:132.47 KB
- 文档页数:8
Linux下的socket网络编程一、基本数据结构socket中最常见的数据结构有in_addr、sockaddr_in、sockaddr。
1、in_addr,用来存储32位的IP地址,其POSIX标准结构体定义如下:struct in_addr{uint32_t s_addr; /*32-bit IPv4 address,network ordered*/};【例1.1】IP地址的设定in_addr test;// INADDR_ANY是一个宏,将当前服务程序绑定到所有地址test.s_addr = htonl(INADDR_ANY);// inet_addr()函数的作用是将字符串形式的IP地址转换成整数值test.s_addr = inet_addr(“192.168.0.1”);2、sockaddr_in,用于存储internet协议族、端口号和IP地址,其结构体原型如下:struct sockaddr_in{short sin_family; //AF_INETu_short sin_port; //16-bit portstruct in_addr sin_addr; //32-bit network ordered IP addresschar sin_zero[8]; //reserved};【例1.2】服务器端地址设定struct sockaddr_in serverAddr;memset(&serverAddr, 0, sizeof(serverAddr)); //清零serverAddr.sin_family = AF_INET; //采用TCP/IP协议serverAddr.sin_port = htons(5050); //端口号serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); //服务程序绑定到所有地址【例1.3】客户端连接服务器struct sockaddr_in serverAddr;memset(&serverAddr, 0, sizeof(serverAddr)); //清零serverAddr.sin_family = AF_INET; //采用TCP/IP协议serverAddr.sin_port = htons(5050); //服务器端口号serverAddr.sin_addr.s_addr = inet_addr(“192.168.0.1”); //服务器IP地址3、sockaddr,通用套接字地址结构在诸如bind()等函数的参数类型中使用,其实质为定义一个通用的类型接口。
其原型为:struct sockaddr{uint8_t sa_len;sa_family_t sa_family; //address family: AF_xxx valuechar sa_data[14]; //protocol-specific address};二、常用套接字函数1、创建套接字#include<sys/types.h>#include<sys/socket.h>int socket(int domain, int type, int protocol);函数返回值:创建新的套接字成功则返回新分配的套接字号,否则返回-1参数说明:·domain常见取值如下:AF_UNIX UNIX域协议(文件系统套接字)AF_INET ARPA因特网协议(UNIX网络套接字)AF_ISO ISO标准协议AF_NS 施乐(Xerox)网络系统协议AF_IPX Novell IPX协议AF_APPLETALK Appletalk DDS·type常见取值如下:SOCK_STREAM 用TCP通信SOCK_DGRAM 用UDP通信SOCK_RAW 原始套接字,作用在网络层,支持对IP包进行操作·protocol,用于指定套接字所采用的特定协议,如果不希望指定任何的协议,可将该参数置为0,即使用默认连接方式2、绑定套接字将一个套接字号与一个特定的地址(包括IP与端口号)信息关联起来,以便当客户端请求时系统可以找到对应的服务程序处理客户端的请求。
#include<sys/socket.h>int bind(int sockfd, const struct sockaddr *address, size_t address_len);函数返回值:绑定成功返回0,否则返回-1并置errno为下表中的一个值EBADF 文件描述符无效ENOTSOCK 文件描述符对应的不是一个套接字EINV AL 文件描述符对应的是一个已命名的套接字EADDRNOTA V AIL 地址不可用EADDRINUSE 地址已经绑定到了一个套接字参数说明:·sockfd:用于指定需要关联的套接字。
·address:需要关联的地址(IP地址+端口号)。
·address_len:地址的长度,一般用sizeof(sockaddr)填充。
【例2.1】函数应用举例,创建一个地址信息,并且将服务套接字进行关联。
int serverSock;struct sockaddr_in serverAddr;if( serverSock = socket(AF_INET, SOCK_STREAM, 0)) < 0){ //创建套接字perror(“socket() error!”);return -1;}memset(&serverAddr, 0, sizeof(serverAddr)); //清零serverAddr.sin_family = AF_INET; //协议族serverAddr.sin_port = htons(8080); //端口号serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); //所要绑定的IP地址//关联套接字if(bind(serverSock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0){perror(“bind() error!”);return -1;}3、创建套接字服务队列为了能够在套接字上接受进入的连接,服务器程序必须创建一个队列用来保存未处理的请求。
他用listen()系统调用来完成这一工作。
listen()函数的作用则是在指定的套接字上监听,以被动的方式等待客户端的连接请求。
#include<sys/socket.h>int listen(int sockfd, size_t backlog);函数返回值:绑定成功返回0,否则返回-1并置errno为EBADF、EINVAL、ENOTSOCK 中的一个值,含义与前面的bind系统调用中描述的一样。
参数说明:·sockfd:用于要关联的服务套接字·backlog:请求队列中的最大长度,一般建议设为5。
4、接受连接一旦服务器程序在创建并命名套接字以后,它就可以通过用accept系统调用来等待客户建立对该套接字的连接,无客户端的连接请求时则阻塞,一直在指定的端口监听。
#include<sys/socket.h>int accept(int sockfd, struct sockaddr *client_address, size_t *clien _address_len);函数返回值:若函数调用成功则返回新的客户端的套接字,失败则返回-1。
参数说明:·sockfd:当前服务套接字。
·client_address:用于保存客户端的地址信息,若不关心客户端,则可置为NULL。
·client_address_len:指向客户端地址长度变量的指针,若不关心客户端,则可置为NULL。
【例2.2】应用举例:等待客户端连接,并作出相应while(1){sockaddr_in clientAddr;socklen_t clientAddr_len = sizeof(clientAddr);int clientfd = accept(serverSock, (struct sockaddr *)&clientAddr,&clientAddr_len);if(clintfd < 0){perror(“accept error!”);return -1;}//do something for the client request//注意,客户端套接字也是和服务套接字一样的资源,应记得释放close(clientfd);}5、请求连接客户程序通过用connect系统调用来将客户端的一个未命名套接字和服务器监听套接字建立连接,从而连接到服务器。
#include<sys/socket.h>int accept(int sockfd, struct sockaddr *server_address, size_t server _address_len);函数返回值:连接成功返回0,否则返回-1并置errno为下表中的一个值EBADF 传递给sockfd的文件描述符无效EALREADY 该套接字上已经有一个正在进行中的连接ETIMEOUT 连接超时ECONNREFUSED 连接请求被服务器拒绝参数说明:·sockfd:当前客户端套接字。
·server_address:服务器地址。
·server _address_len:服务器地址的长度,一般用sizeof(server_address)填充。
6、用于TCP连接的发送数据和接收数据函数#include<sys/socket.h>int send(int sockfd, const char *data_buf, size_t data_buf_len, int flags);int recv(int sockfd, const char *data_buf, size_t data_buf_len, int flags);函数返回值:若调用成功则返回实际发送/接收成功的字符个数,调用失败返回-1参数说明:·sockfd:用于标记已连接的套接字。
·data_buf:用于发送/接收数据的缓冲区的首地址。
·data_buf_len:用于发送/接收数据的缓冲区的大小。
·flags:用于设定发送/接收数据的控制参数,一般可设为0。