基本概念
唯一标示一个进程的三元组
(协议,本地ip,本地端口号)
一个三元祖可以唯一标示一个网络连接的一部分。一个五元组可以标示一个网络连接的两端
(协议,本地ip,本地端口号,远地ip,远地端口号)
套接字
- 创建套接字
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
socket函数有三个参数,第一个参数可以为AF_INET
、AF_INET6
、AF_LOCAL
、AF_ROUTE
,AF_INET
代表Internet。
第二个参数为套接字种类.
- 指定本地地址bind()
当一个套接字用socket()创建后,存在一个名字空间(地址族),但它没有被命名。bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字号联系起来,即将名字赋予套接字,以指定本地半相关。其调用格式如下:
bind(server_socket, (struct sockaddr *)&server_sockaddr, sizeof(server_sockaddr)
struct sockaddr_in server_sockaddr;
bzero(&server_sockaddr, sizeof(server_sockaddr));
设置地址族和端口
server_sockaddr.sin_family = AF_INET;
// host to net short
server_sockaddr.sin_port = htons(MYPORT);
// host to net long, 网络字节序使用Big-Endian
// Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- 套接字连接
服务器端设置连接,监听连接──listen()
此调用用于面向连接服务器,表明它愿意接收连接。listen()需在accept()之前调用,其调用格式如下:
int listen(int s, int backlog);
客户端连接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
accept使用
char buffer[BUFFER_SIZE];
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);
int conn = accept(server_socket, (struct sockaddr *)&client_addr, &length);
在用做accept()调用的参数前应该先调用过listen()。accept()用于面向连接服务器。参数addr和addrlen存放客户方的地址信息。调用前,参数addr 指向一个初始值为空的地址结构,而addrlen 的初始值为0;调用accept()后,服务器等待从编号为s的套接字上接受客户连接请求,而连接请求是由客户方的connect()调用发出的。当有连接请求到达时,accept()调用将请求连接队列上的第一个客户方套接字地址及长度放入addr 和addrlen,并创建一个与s有相同特性的新套接字号。新的套接字可用于处理服务器并发请求。
socket()指定五元组中的协议元,它的用法与是否为客户或服务器、是否面向连接无关。bind()指定五元组中的本地二元,即本地主机地址和端口号,其用法与是否面向连接有关:在服务器方,无论是否面向连接,均要调用bind(),若采用面向连接,则可以不调用bind(),而通过connect()自动完成。若采用无连接,客户方必须使用bind()以获得一个唯一的地址。
- 数据传输──send()与recv()
//conn为accept的返回值
send(conn, buffer, len, 0);
-
输入/输出多路复用──select()
-
关闭socket
closesocket(SOCKET s);
网友评论