1、TCP服务器端的默认函数调用顺序
socket()-->bind()-->listen()-->accept()-->read()/write()-->close()
2、函数详解
int listen(int sock, int backlog);
sock:希望进入等待连接请求状态的套接字文件描述符,传递的描述符套接字参数为服务器端套接字
backlog:连接请求等待队列的长度。该值与服务器端的特性有关,像频繁接受请求的Webfuwu服务器端至少应为15。
int accept(int sock, struct sockaddr *addr, socklen_t addrlen);
sock:希望进入等待连接请求状态的套接字文件描述符,传递的描述符套接字参数为服务器端套接字
addr:保存发起连接请求的客户端地址信息的变量地址值
addrlen:第二个参数的长度
3、服务器端程序
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int serv_sock;
int clnt_sock;
//声明套接字
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr
socklen_t clnt_addr_size;
//需要发送的信息
char message[] = "hello world";
//创建套接字
serv_sock = sock(PF_INET, SOCK_STREAM, 0);
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(argv[1]));
//进行绑定
bind(serv_sock, (struct sockaddr*)serv_addr, sizeof(serv_addr));
//监听
listen(serv_sock, 5);
//接受
clnt_addr_size = sizeof(clnt_addr);
clnt_sock = accept(serv_sock, (struct sockaddr*)clnt_addr, &clnt_addr_size);
write(clnt_sock, message, sizeof(message));
close(serv_sock);
close(clnt_sock);
return 0;
}
4、 TCP客户端的默认函数调用顺序
socket()-->connect()-->read()/write()-->close()
5、函数详解
int connect(int sock, (struct sockaddr*)servsddr, socklen_t addrlen);
所谓连接请求并不意味着服务器端调用accept函数,其实是服务器端把连接请求信息记录到等待队列。因此connect函数返回后并不立即进行数据交换;客户端的IP地址和端口在调用connect函数时自动分配,无需调用bind函数进行分配。
6、服务器端程序
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int clnt_sock;
//声明套接字
struct sockaddr_in serv_addr;
socklen_t clnt_addr_size;
char message[30];
int str_len;
//创建套接字
clnt_sock = sock(PF_INET, SOCK_STREAM, 0);
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
serv_addr.sin_port = htons(atoi(argv[2]));
connect(clnt_sock, (struct sockaddr*)serv_addr, sizeof(serv_addr));
str_len = read(clnt_sock, message, sizeof(message)-1);
close(clnt_sock);
return 0;
}