1、通过socket()函数实现创建套接字。 2、往sockaddr_in结构体中,填充对方的地址信息。 3、通过bind函数,绑定自己设备信息(上一步的sockaddr_in结构体)。 4、通过listen()函数,将该套接字和套接字对应的连接队列长度告诉 Linux 内核。 4、通过accept()函数,从处于 established 状态的连接队列头部取出一个已经完成的连接,如果这个队列没有已经完成的连接,accept()函数就会阻塞,直到取出队列中已完成的用户连接为止。 5、通过recv()接收数据。 6、通过send()发送数据。
{ int listenfd, connfd; struct sockaddr_in myaddr;
if ((listenfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("fail to socket"); exit(-1); }
bzero(&myaddr, sizeof(myaddr)); myaddr.sin_family = PF_INET; myaddr.sin_port = htons(atoi(argv[2])); myaddr.sin_addr.s_addr = inet_addr(argv[1]); if (bind(listenfd, (SA *)&myaddr, sizeof(myaddr)) < 0) { perror("fail to bind"); exit(-1); }
if (listen(listenfd, 5) < 0) //第二个参数(backlog)的作用:告诉内核连接队列的长度。 //内核为任何一个给定的监听套接口维护两个队列: //1、未完成连接队列(incomplete connection queue),每个这样的 SYN 分节对应其中一项:已由某个客户发出并到达服务器,而服务器正在等待完成相应的 TCP 三次握手过程。这些套接口处于 SYN_RCVD 状态。 //2、已完成连接队列(completed connection queue),每个已完成 TCP 三次握手过程的客户对应其中一项。这些套接口处于 ESTABLISHED 状态。 //一般此参数填写5 { perror("fail to listen"); exit(-1); }
while (1) { if ((connfd = accept(listenfd, NULL, NULL)) < 0) //从处于 established 状态的连接队列头部取出一个已经完成的连接,如果这个队列没有已经完成的连接,accept()函数就会阻塞,直到取出队列中已完成的用户连接为止。 //参数一:利用系统调用socket()建立的套接字描述符,通过bind()绑定到一个本地地址(一般为服务器的套接字),并且通过listen()一直在监听连接; //参数二:服务器等套接字的地址 //参数三:套接字长度 { perror("fail to accept"); exit(-1); } close(connfd); } return 0; }
{ //设置一个socket地址结构client_addr,代表客户机internet地址, 端口 struct sockaddr_in client_addr; bzero(&client_addr, sizeof(client_addr)); //把一段内存区的内容全部设置为0 client_addr.sin_family = AF_INET; //internet协议族 client_addr.sin_addr.s_addr = htons(INADDR_ANY); //INADDR_ANY表示自动获取本机地址 client_addr.sin_port = htons(0); //0表示让系统自动分配一个空闲端口 //创建用于internet的流协议(TCP)socket,用client_socket代表客户机socket int client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket < 0) { exit(1); } //把客户机的socket和客户机的socket地址结构联系起来 if (bind(client_socket, (struct sockaddr *)&client_addr, sizeof(client_addr))) { exit(1); }
//设置一个socket地址结构server_addr,代表服务器的internet地址, 端口 struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; if (inet_aton(server_ip, &server_addr.sin_addr) == 0) //服务器的IP地址来自程序的参数 { exit(1); } server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); socklen_t server_addr_length = sizeof(server_addr); //向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接 if (connect(client_socket, (struct sockaddr *)&server_addr, server_addr_length) < 0) { exit(1); } return client_socket; }
send(client_socket, buffer, len, 0);
length = recv(socket_id, buffer, BUFFER_SIZE, 0); if (length > 0) { msgarrvd(buffer); bzero(buffer, BUFFER_SIZE); }