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);
}