网络编程

基本概念

唯一标示一个进程的三元组

(协议,本地ip,本地端口号)

一个三元祖可以唯一标示一个网络连接的一部分。一个五元组可以标示一个网络连接的两端

(协议,本地ip,本地端口号,远地ip,远地端口号)

套接字

  1. 创建套接字
int server_socket = socket(AF_INET, SOCK_STREAM, 0);

socket函数有三个参数,第一个参数可以为AF_INETAF_INET6AF_LOCALAF_ROUTE,AF_INET代表Internet。
第二个参数为套接字种类.

  1. 指定本地地址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);
  1. 套接字连接
    服务器端设置连接,监听连接──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()以获得一个唯一的地址。

  1. 数据传输──send()与recv()
//conn为accept的返回值
send(conn, buffer, len, 0);
  1. 输入/输出多路复用──select()

  2. 关闭socket

closesocket(SOCKET s);

你可能感兴趣的:(网络编程)