1.IP地址格式转换函数
int inet_pton(int af, const char *src, void *dst);
IP地址在“点分十进制”和“二进制整数”之间转换
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define IPADDR "192.168.1.102"
// 0x66 01 a8 c0
// 102 1 168 192
// 网络字节序,其实就是大端模式
int main(void)
{
int ret = 0;
struct in_addr addr = {0};
ret = inet_pton(AF_INET, IPADDR, &addr);
if(ret != 1)
{
printf("inet_pton error\n");
return -1;
}
printf("addr = 0x%x.\n", addr.s_addr);// 0x6601a8c0
}
inet_ntop 将 IPv4 和 IPv6 地址从 "二进制" 转换为 "点分十进制"
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define IPADDR "192.168.1.102"
// 0x66 01 a8 c0
// 102 1 168 192
// 网络字节序,其实就是大端模式
int main(void)
{
struct in_addr addr = {0};
char buf[50] = {0};
addr.s_addr = 0x6601a8c0;
inet_ntop(AF_INET, &addr, buf, sizeof(buf));
printf("ip addr = %s.\n", buf);//ip addr = 192.168.1.102.
return 0;
}
inet_addr 将字符串形式的IP地址 -> 网络字节顺序 的整型值
in_addr_t inet_addr(const char *cp);
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define IPADDR "192.168.1.102"
// 0x66 01 a8 c0
// 102 1 168 192
// 网络字节序,其实就是大端模式
int main(void)
{
in_addr_t addr = 0;
addr = inet_addr(IPADDR);
printf("addr = 0x%x.\n", addr);//addr = 0x6601a8c0.
}
2.soekct实践编程
2.1 服务器端程序编写
(1)socket
(2)bind
(3)listen
(4)accept 返回值是一个fd,accept正确返回就表示我们已经和前来连接我的客户端之间建立了一个TCP连接了,以后我们就要通过这个连接来和客户端进行读写操作,读写操作就需要一个fd,这个fd就由accept来返回了。
注意:socket返回的fd叫做监听fd,是用来监听客户端的,不能用来和任何客户端进行读写;accept返回的fd叫做连接fd,用来和连接那端的客户端程序进行读写。
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
//服务器端信息
#define SERPORT 9003
#define SERADDR "192.168.129.128" // ifconfig看到的
#define BACKLOG 100
int main(void)
{
// 第1步:先socket打开文件描述符
int sockfd = -1, ret = -1, clifd = -1;
socklen_t len = 0;
struct sockaddr_in seraddr = {0};
struct sockaddr_in cliaddr = {0};
char ipbuf[30] = {0};
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sockfd)
{
perror("socket");
return -1;
}
printf("socketfd = %d.\n", sockfd);
// 第2步:bind绑定sockefd和当前电脑的ip地址&端口号
seraddr.sin_family = AF_INET; // 设置地址族为IPv4
seraddr.sin_port = htons(SERPORT); // 设置地址的端口号信息
seraddr.sin_addr.s_addr = inet_addr(SERADDR); // 设置IP地址
ret = bind(sockfd, (const struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret < 0)
{
perror("bind");
return -1;
}
printf("bind success.\n");
// 第三步:listen监听端口
ret = listen(sockfd, BACKLOG); // 阻塞等待客户端来连接服务器
if (ret < 0)
{
perror("listen");
return -1;
}
// 第四步:accept阻塞等待客户端接入
clifd = accept(sockfd, (struct sockaddr *)&cliaddr, &len);
printf("连接已经建立,client fd = %d.\n", ret);
return 0;
}
2.2客户端程序编写
(1)socket
(2)connect
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERADDR "192.168.129.128" // 服务器开放给我们的IP地址和端口号
#define SERPORT 9003
int main(void)
{
// 第1步:先socket打开文件描述符
int sockfd = -1, ret = -1;
struct sockaddr_in seraddr = {0};
struct sockaddr_in cliaddr = {0};
// 第1步:socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sockfd)
{
perror("socket");
return -1;
}
printf("socketfd = %d.\n", sockfd);
// 第2步:connect链接服务器
seraddr.sin_family = AF_INET; // 设置地址族为IPv4
seraddr.sin_port = htons(SERPORT); // 设置地址的端口号信息
seraddr.sin_addr.s_addr = inet_addr(SERADDR); // 设置IP地址
ret = connect(sockfd, (const struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret < 0)
{
perror("listen");
return -1;
}
printf("connect result, ret = %d.\n", ret);
return 0;
}
all:
gcc server.c -o ser
gcc client.c -o cli
clean:
rm ser cli *.o
先运行server然后打开另一个终端运行client