基于Linux的C++之网络编程

xiaoxiao2021-02-28  5

套接字的基本概念套接字函数本地套接字示例:服务器端本地套接字示例,客户端本地套接字示例:运行网络套接字示例:客户端

套接字的基本概念

通信类型: 控制套接字如何传输和处理数据,数据以包的形式传输

连接(connection)类型:确保所有包依序传输,如果丢包,则请求重传数据报(datagram)类型:不保证包的到达顺序,包可能丢失

名空间: 指定套接字地址格式

本地名空间:套接字地址为普通文件名Internet名空间:套接字地址由Internet地址和端口号(用于区分一台主机上的多个套接字)确定

协议: 确定数据如何传输

套接字函数

socket()函数: 创建套接字

原型:int socket(int domain,int type,int protocol);参数:名空间、通信类型和协议名空间:PF_LOCAL(本地)或PF_INET(Internet)通信类型:SOCK_STREAM(连接类型)或SOCK_DGRAM(数据报类型)协议:传递0,让系统自动选择协议(通常为最佳协议)返回值:套接字描述符

close()函数: 释放套接字

原型:int close(int fd);

connect()函数: 创建两个套接字之间的连接

客户发起此系统调用,试图与服务器建立套接字连接原型:int connect(int sockfd,const struct sockaddr* addr,socklen_t addrlen);参数:sockfd 为文件描述符; addr 为指向套接字地址结构体指针(服务器地址);addrlen 为服务器地址字符串的长度返回值:0 连接成功; -1 连接失败

send()函数: 发送数据

原型: ssize_t send(int sockfd,const void* buf,size_t len,int flags);只有在套接字处于连接状态时才可调用

bind()函数: 绑定套接字与其服务器地址

原型:int bind(int sockfd,const struct sockaddr* addr,socklen_t addrlen);

listen()函数: 侦听客户连接

原型:int listen(int sockfd,int backlog);参数:backlog 指定有多少个连接可以进入队列,超出该值的连接将被抛弃

accept()函数: 接受连接,为该连接创建一个新的套接字

原型 int accept(int sockfd,struct sockaddr* addr,socklen_t addrlen);参数: addr 为指向套接字地址结构体(客户地址)的指针返回值:创建一个新的套接字,以接受客户连接,返回值为新的套接字文件描述符原先套接字文件描述符可以继续接受新连接

本地套接字示例:服务器端

#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> //持续读取消息,直到套接字关闭或接收到客户发送的“quit”消息 // 前者返回true,后者返回 false,服务器随后将停止服务 bool Serve(int client_socket) { while (true) { int length; char* msg; //从套接字中读取文本消息的长度,返回值为0表示客户连接已关闭 if(read(client_socket,&length,sizeof(length)) == 0) return true; msg = new char[length]; read(client_socket,msg,length); std::cout<<msg<<std::endl; if(!strcmp(msg,"quit")) {delete[] msg,msg = NULL;return false;} else delete[] msg, msg = NULL; } } int main(int argc,char* const argv[]) { const char* const socket_name = argv[1]; ing socket_fd; struct sockaddr_un name; bool serving = true; //创建套接字 socket_fd = socket(PF_LOCAL,SOCK_STREAM,0); //设定服务器性质 name.sun_family = AF_LOCAL; strcpy(name.sun_path,socket_name); // 绑定套接字 bind(socket_fd,(struct sockaddr*)&name,SUN_LEN(&name)); //侦听客户连接 listen(socket_fd,5); //重复接受连接,直到某个客户发出“quit”消息 while(serving) { struct sockaddr_un client_name; socklen_t client_name_len; int client_socket_fd; //接受客户连接请求 client_socket_fd = accept(socket_fd,(struct sockaddr*)&client_name,&client_name_len); serving = Serve(client_socket_fd); //服务连接请求 close(socket_fd);//关闭客户连接 } close(socket_fd); unlink(socket_name); //删除套接字文件 return 0; }

本地套接字示例,客户端

#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> void SendMsg(int socket_fd,const char* msg) { int length = strlen(msg) + 1; write(socket_fd,&length,sizeof(length)); write(socket_fd,msg,length); } int main(int argc, char const *argv[]) { const char* const socket_name = argv[1]; const char* const msg = argv[2]; int socket_fd; struct sockaddr_un name; //创建套接字 socket_fd = socket(PF_LOCAL,SOCK_STREAM,0); //套接字地址中存储服务器名称 name.sun_family = AF_LOCAL; strcpy(name.sun_path,socket_name); //连接 connect(socket_fd,(struct sockaddr*)&name,SUN_LEN(&name)); //发送消息 SendMsg(socket_fd,msg); close(socket_fd); return 0; }

本地套接字示例:运行

程序测试运行

编译链接服务端程序和客户端程序进入服务端程序目录,在终端输入:./server/tmp/socket; ./server 为服务器端程序名, /tmp/socket 为本服务器启动后的套接字文件名进入客户端程序目录,在终端中输入:./client/tmp/socket"Hello World!"; ./client 为客户端程序名停止服务器,在客户端输入命令:./client/tmp/socket"quit"

网络套接字示例:客户端

#include <iostream> #include <stdio.h> #include <netinet/in.h> #include <netdb.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> // 请求Web服务器的主页 void GetHomepage(int socket_fd) { char buffer[8192]; sprintf(buffer,"GET /\n"); write(socket_fd,buffer,strlen(buffer)); while(true){ ssize_t count = read(socket_fd,buffer,8192); if(count == 0) return; fwrite(buffer,sizeof(char),count,stdout); } } int main(int argc, char const *argv[]) { int socket_fd; struct sockaddr_in name; struct hostent* hostinfo; socket_fd = socket(PF_INET,SOCK_STREAM,0); name.sin_family = AF_INET; hostinfo = gethostbname(argv[1]); if(hostinfo == NULL) return 1; else name.sin_addr = *((struct in_addr*)hostinfo ->h_addr); name.sin_port = htons(80); if(connect(socket_fd,(struct in_addr*)&name,sizeof(struct sockaddr_in)) == -1) { perror("Failure to connect the server."); return 2; } GetHomepage(socket_fd); return 0; }

“`

转载请注明原文地址: https://www.6miu.com/read-2350036.html

最新回复(0)