步骤:
- socket()创建套接字
- connect()连接
- 读写数据
- close()关闭
使用的工具:NetAssist网络助手
1、几个主要使用函数:
//创建套接字API
#include<sys/socket.h>
int socket(int domain, int type, int prorocol);
/*
创建套接字
参数:
domain: AF_INET(表示使用 IPv4 地址)
type: SOCK_STREAM(流式套接字)
protocol: 0(使用0系统根据 AF_INET 和 SOCK_STREAM 来自动选择 TCP 协议。)
成功返回文件描述符,失败返回-1
*/
//连接服务器
#include<sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
/*
功能:连接服务器
参数:
sockfd: socket套接字
addr: ipv4套接字结构体的地址
addrlen: ipv4套接字结构体的长度
*/
在connet函数中,使用了 sockaddr 的结构体,这个结构体有两种类型,分别是ipv4(sockaddr_in)和ipv6(sockaddr_in6),下面是ipv4的结构体:
struct sockaddr_in{
sa_family_t sin_family; //address family: AF_INET
in_port_t sin_port; //port in network byte order
struct in_addr sin_addr; //internet address
};
//internet address
struct in_addr{
uint32_t s_addr; //address in network byte order
}
/*
sin_family: 协议 AF_INET
sin_port: 端口
sin_addr: ip地址
*/
2、使用NetAssist创建服务器
3、测试代码
#include<stdio.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
int main()
{
//创建套接字
int sock_fd;
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
//连接服务器
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080); //转大端存储
inet_pton(AFINET, "192.168.10.103", &addr.sin_addr.s_addr); //点分十进制转大端
connet(sock_fd, (struct sockaddr *)&addr, sizeof(addr)); //连接服务器,注意这里使用了强转结构体类型
//读写数据
char buf[1024] = "";
while(1)
{
int n = read(STDIN_FILENO, buf, sizeof(buf)); // STDIN_FILENO为标准输入文件描述符;从标准输入中读取数据到buf,n为读到的数据字节数
write(sock_fd, buf, n); // 写数据到服务器,sock_fd为服务器套接字的文件描述符
n = read(sock_fd, buf, sizeof(buf)); //从服务器读取数据
write(STDOUT_FILENO, buf, n); // 将从服务器读到的数据写到标准输出
}
close(sock_fd); //关闭文件
return 0;
}
4、使用测试
从终端(客户端)输入数据:
服务器接收到数据:
在服务器选择要发送的客户端
客户端接收到数据
测试完毕!