网络socket编程(c语言)

您所在的位置:网站首页 c语言socket网络编程项目 网络socket编程(c语言)

网络socket编程(c语言)

2023-12-27 12:54| 来源: 网络整理| 查看: 265

一.socket通信简介

Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议,主要利用三元组【ip地址,协议,端口】。 socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。 Socket()函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。Socket是应用层与TCP/IP协议族通信的中间软件抽象层。 在这里插入图片描述 二.网络socket客户端和服务器端连接过程如下: 在这里插入图片描述

1.1 socket() int socket(int domain,int type, int protocol); 返回值: 成功:返回指向新创建的socket的文件描述符,失败:返回-1。

domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。 type:创建的套接字的类型,常用SOCK_STREAM(流式套接字),SOCK_DGRAM(数据报套接字)

protocol: 传0 表示使用默认协议。

1.2 bind() int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 返回值:函数执行成功返回0,否则返回-1, 并设置错误代码。

sockfd:需要绑定的套接字文件描述符。 addr:存入网络类型,网络地址和端口号的结构体。 addrlen:addr结构体的长度。

ipv4使用的结构体是struct sockaddr_in类型,所以绑定时需要强制类型转换成struct sockaddr类型 struct sockaddr_in { sa_family_t sin_family; /* 2 bytes address family, AF_xxx such as AF_INET / in_port_t sin_port; / 2 bytes port*/ struct in_addr sin_addr; /* 4 bytes IPv4 address*/ unsigned char sin_zero[8]; /* 8 bytes unused padding data, always set be zero */ };

struct sockaddr { sa_family_t sa_family; /* 2 bytes address family, AF_xxx / char sa_data[14]; / 14 bytes of protocol address */ }

在使用bind时常用的两个函数:htons和htonl,在将一个地址绑定到socket的时候,先将主机字节序转换成为网络字节序 serv_addr.sin_port = htons(LISTEN_PORT); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

IP地址“127.0.0.1”这是点分十进制形式的字符串形式,而在结构体struct sockaddr_in 中IP地址是以32位(即4字节整形类型)数据保存的,这时我们可以调用 inet_aton() 函数将点分十进制字符串转换成 32位整形类型

1.3 listen() int listen(int sockfd,int backlog); 返回值:成功返回0,失败返回-1。 sockfd: socket文件描述符 backlog: 排队建立3次握手队列和刚刚建立3次握手队列的链接数和

1.4 accept() int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

属性相同的连接套接字,并为这个套接字分配一个文件描述符,然后以这个描述符返回 返回值:若成功则返回一个非负整数标识这个连接套接字,发生错误时返回-1。 sockfd:一个正在用于监听功能下的套接字的文件描述符。 addr:用于储存接受到的客户端的网络信息的结构体(参考bind下的使用) addrlen:addr结构体长度

1.5 connect() int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd: 客户端的socket()创建的描述字 addr: 要连接的服务器的socket地址信息,这里面包含有服务器的IP地址和端口等信息 addrlen: socket地址的长度

客户端server.c程序编写

/********************************************************************************* * Copyright: (C) 2021 jiaoer237 * All rights reserved. * * Filename: socket_server.c * Description: This file * * Version: 1.0.0(11/21/2021) * Author: yanp * ChangeLog: 1, Release initial version on "11/21/2021 01:59:13 PM" * ********************************************************************************/ #include #include #include #include #include #include #include #include #define PORT 8899 #define BACKLOG 13 int socket_server_init(char *listen_ip,int listen_port); int main() { int listen_fd,clien_fd=-1; struct sockaddr_in cli_addr; socklen_t cliaddr_len; char buf[1024]; int rv=-1; listen_fd=socket_server_init(NULL,PORT);/*初始化socket函数*/ while(1) { printf("\nstart waiting and accept new client connect...\n"); clien_fd=accept(listen_fd,(struct sockaddr*)&cli_addr,&cliaddr_len);/*accept调用*/ if(clien_fd printf("read data from socket[%d] failure:%s\n",clien_fd,strerror(errno)); close(clien_fd); continue; } else if(0==rv) { printf("read data from socket[%d] failure:%s\n",clien_fd,strerror(errno)); close(clien_fd); continue; } printf("read %d data from server client [%d] and echo it back:'%s'\n",rv,clien_fd,buf); if(write(clien_fd,buf,rv) int listenfd; struct sockaddr_in servaddr; if((listenfd=socket(AF_INET,SOCK_STREAM,0)) printf("setsockopt failure:%s",strerror(errno)); return -2; } memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(PORT); if(!listen_ip)/*加入传入IP地址则监听指定ip,否则监听所有ip*/ { servaddr.sin_addr.s_addr=htonl(INADDR_ANY); } else { servaddr.sin_addr.s_addr=htonl(listen_port); } if(bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) int conn_fd = -1; int rv = -1; char buf[1024]; struct sockaddr_in serv_addr; conn_fd=socket(AF_INET,SOCK_STREAM,0);/*socket创建客户端的描述符*/ if(conn_fd printf("client[%d] connect to server[%s:%d] failure:%s\n",conn_fd,SERVER_IP,SERVER_PORT,strerror(errno)); return -1; } if(write(conn_fd,MSG_STR,strlen(MSG_STR)) printf("read data from server failure:%s\n",strerror(errno)); return -3; } else if(rv==0) { printf("client connetc to server get disconnect\n"); return -4; } printf("read %d bytes from server:'%s'\n",rv,buf); return 0; }

在这里插入图片描述 在这里插入图片描述 客户端连接服务器之后进行读写操作



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3