Socket、本身有“插座”的意思,在Linux环境下,用于表示进程间的网络通信的特殊文件类型,本质为内核借助缓冲区形成的伪文件。
既然是文件,我们就可以使用文件描述符引用套接字,与管道类似,Linux系统将其封装成文件的目的是为了统一接口,使得读写套接字和读写文件的操作保持一致,不过与管道还是有区别的,管道主要应用于本地进程间的通信,而套接字多应用于网络进程间的数据传输。
在TCP/IP协议层中,我们把“IP地址+TCP或UDP端口号”标识的网络中的唯一进程叫做Socket,那么两个网络进程之间数据的传输,就必须建立联系。
在网络通信中,套接字一定是成对出现的,一端的发送缓冲区对应另一端的接收缓冲区。我们使用同一个文件描述符发送缓冲区
网络应用程序设计模式: |
优缺点: |
网络编程知识:
网络字节序: |
Socket模型创建 |
服务器端: |
//创建监听套接字
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
// int listen_fd;
// listen_fd = socket(AF_INET,SOCK_STREAM,0);
//SOCK_STREAM(面向字节流,可靠的,按顺序的连接,基于TCP)
//SOCK_DGRAM(无连接的,固定数据长度的传输调用,不可靠的,基于UDP传输)
//设置结构体,转换端口与ip
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(atoi(argv[2])); //端口
local.sin_addr.s_addr = inet_addr(argv[1]); //IP
//绑定,监听套结字与自己服务器ip绑定
int bind(int sockfd, const struct sockaddr addr,
socklen_t addrlen);
//bind(listen_fd,(struct sockaddr_in)&local,sizeof(local) )
//设置监听模式,创建队列,把用户信息填充到队列
int listen (int sockfd, int backlog)
// listen (listen_fd,10);
//拿到监听者信息,建立链接,返回rw_sockfd
struct sockaddr_in client_addr;
int* rw_sockfd = NULL;
while(1)
{
rw_sockfd =accept(listen_fd,(struct sockaddr_in*)&client_addr,sizeof(client_addr));
write();
read();
close(rw_sockfd)
}
//这是一个死循环过程,每次循环处理一个客户端连接,服务器与客户端数据传输都是通过accept()新得到的rw_sockfd来完成的,当数据传输结束,关闭rw_sockfd,而不关闭listenfd,再次循环进行下一轮监听
<table><tr><td bgcolor=#7FFFD4>客户端: </td></tr></table>
//创建套接字
int socket(int domain, int type, int protocol);
// int sockfd;
// sockfd = socket(AF_INET,SOCK_STREAM,0);
//设置结构体状态,拿到服务器端ip与port
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(atoi(argv[2]));//port端口
local.sin_addr.s_addr = inet_addr(argv[1]);//本地ip
//向服务器发起连接请求
int connect(int sockfd,const struct sockaddr* addr,socklen_t addrlen)
// connect(sockfd,(struct sockaddr_in*)&local,sizeof(local)))