4 TCP通信code

 字节序、ip地址和整数转换、tcp/ip通信 

 0706笔记就记了,但是具体是哪个函数遗忘了,赶紧来复习下

重点:0916面试问道了,ip地址和整数怎么转换

/*

#include <arpa/inet.h>

// p:点分十进制的IP字符串,n:表示network,网络字节序的整数

int inet_pton(int af, const char *src, void *dst);

af:地址族: AF_INET AF_INET6

src:需要转换的点分十进制的IP字符串

dst:转换后的结果保存在这个里面

   

// 将网络字节序的整数,转换成点分十进制的IP地址字符串

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

af:地址族: AF_INET AF_INET6

src: 要转换的ip的整数的地址

dst: 转换成IP地址字符串保存的地方

size:第三个参数的大小(数组的大小)

返回值:返回转换后的数据的地址(字符串),和 dst 是一样的

   

*/

 

 

 

  • 字节序

byteorder.c文件

判断当前机器的字节序

/*

字节序:字节在内存中存储的顺序。

小端字节序:数据的高位字节存储在内存的高位地址,低位字节存储在内存的低位地址

大端字节序:数据的低位字节存储在内存的高位地址,高位字节存储在内存的低位地址

*/

   

// 通过代码检测当前主机的字节序

#include <stdio.h>

   

int main() {

union {

short value; // 2字节

char bytes[sizeof(short)]; // char[2]

} test;

   

test.value = 0x0102;

if((test.bytes[0] == 1) && (test.bytes[1] == 2)) {

printf("大端字节序\n");

} else if((test.bytes[0] == 2) && (test.bytes[1] == 1)) {

printf("小端字节序\n");

} else {

printf("未知\n");

}

   

return 0;

}

   

bytrtrans.c文件

字节序转换

/*

网络通信时,需要将主机字节序转换成网络字节序(大端),

另外一段获取到数据以后根据情况将网络字节序转换成主机字节序。

   

// 转换端口

uint16_t htons(uint16_t hostshort);                // 主机字节序 - 网络字节序

uint16_t ntohs(uint16_t netshort);                // 主机字节序 - 网络字节序

   

// IP

uint32_t htonl(uint32_t hostlong);                // 主机字节序 - 网络字节序

uint32_t ntohl(uint32_t netlong);                // 主机字节序 - 网络字节序

*/

   

#include <stdio.h>

#include <arpa/inet.h>

   

int main() {

// htons 转换端口

unsigned short a = 0x0102;

printf("a : %x\n", a);

unsigned short b = htons(a);

printf("b : %x\n", b);

   

printf("=======================\n");

   

// htonl 转换IP

char buf[4] = {192, 168, 1, 100};

int num = *(int *)buf;

int sum = htonl(num);

unsigned char *p = (char *)&sum;

   

printf("%d %d %d %d\n", *p, *(p+1), *(p+2), *(p+3));

   

printf("=======================\n");

   

// ntohl

unsigned char buf1[4] = {1, 1, 168, 192};

int num1 = *(int *)buf1;

int sum1 = ntohl(num1);

unsigned char *p1 = (unsigned char *)&sum1;

printf("%d %d %d %d\n", *p1, *(p1+1), *(p1+2), *(p1+3));

 

// ntohs

   

   

return 0;

}

   

   

   

   

  • ip地址和整数转换

iptrans.c文件

 

/*

#include <arpa/inet.h>

// p:点分十进制的IP字符串,n:表示network,网络字节序的整数

int inet_pton(int af, const char *src, void *dst);

af:地址族: AF_INET AF_INET6

src:需要转换的点分十进制的IP字符串

dst:转换后的结果保存在这个里面

   

// 将网络字节序的整数,转换成点分十进制的IP地址字符串

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

af:地址族: AF_INET AF_INET6

src: 要转换的ip的整数的地址

dst: 转换成IP地址字符串保存的地方

size:第三个参数的大小(数组的大小)

返回值:返回转换后的数据的地址(字符串),和 dst 是一样的

   

*/

#include <stdio.h>

#include <arpa/inet.h>

   

int main() {

// 创建一个ip字符串,点分十进制的IP地址字符串

char buf[] = "192.168.1.4";

unsigned int num = 0;

   

// 将点分十进制的IP字符串转换成网络字节序的整数

inet_pton(AF_INET, buf, &num);

unsigned char * p = (unsigned char *)&num;

printf("%d %d %d %d\n", *p, *(p+1), *(p+2), *(p+3));

   

   

// 将网络字节序的IP整数转换成点分十进制的IP字符串

char ip[16] = "";

const char * str = inet_ntop(AF_INET, &num, ip, 16);

printf("str : %s\n", str);

printf("ip : %s\n", str);

printf("%d\n", ip == str);

   

return 0;

}

   

   

   

   

  • 代码实现tcp/ip通信

sever.c文件

服务端

// TCP 通信的服务器端

   

#include <stdio.h>

#include <arpa/inet.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

   

int main() {

   

// 1.创建socket(用于监听的套接字)

int lfd = socket(AF_INET, SOCK_STREAM, 0);

   

if(lfd == -1) {

perror("socket");

exit(-1);

}

   

// 2.绑定

struct sockaddr_in saddr;

saddr.sin_family = AF_INET;

// inet_pton(AF_INET, "192.168.193.128", saddr.sin_addr.s_addr);

saddr.sin_addr.s_addr = INADDR_ANY; // 0.0.0.0

saddr.sin_port = htons(9999);

int ret = bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr));

   

if(ret == -1) {

perror("bind");

exit(-1);

}

   

// 3.监听

ret = listen(lfd, 8);

if(ret == -1) {

perror("listen");

exit(-1);

}

   

// 4.接收客户端连接

struct sockaddr_in clientaddr;

int len = sizeof(clientaddr);

int cfd = accept(lfd, (struct sockaddr *)&clientaddr, &len);

 

if(cfd == -1) {

perror("accept");

exit(-1);

}

   

// 输出客户端的信息

char clientIP[16];

inet_ntop(AF_INET, &clientaddr.sin_addr.s_addr, clientIP, sizeof(clientIP));

unsigned short clientPort = ntohs(clientaddr.sin_port);

printf("client ip is %s, port is %d\n", clientIP, clientPort);

   

// 5.通信

char recvBuf[1024] = {0};

while(1) {

 

// 获取客户端的数据

int num = read(cfd, recvBuf, sizeof(recvBuf));

if(num == -1) {

perror("read");

exit(-1);

} else if(num > 0) {

printf("recv client data : %s\n", recvBuf);

} else if(num == 0) {

// 表示客户端断开连接

printf("clinet closed...");

break;

}

   

char * data = "hello,i am server";

// 给客户端发送数据

write(cfd, data, strlen(data));

}

 

// 关闭文件描述符

close(cfd);

close(lfd);

   

return 0;

}

   

client.c文件

客户端

// TCP通信的客户端

   

#include <stdio.h>

#include <arpa/inet.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

   

int main() {

   

// 1.创建套接字

int fd = socket(AF_INET, SOCK_STREAM, 0);

if(fd == -1) {

perror("socket");

exit(-1);

}

   

// 2.连接服务器端

struct sockaddr_in serveraddr;

serveraddr.sin_family = AF_INET;

inet_pton(AF_INET, "192.168.193.128", &serveraddr.sin_addr.s_addr);

serveraddr.sin_port = htons(9999);

int ret = connect(fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

   

if(ret == -1) {

perror("connect");

exit(-1);

}

 

// 3. 通信

char recvBuf[1024] = {0};

while(1) {

   

char * data = "hello,i am client";

// 给客户端发送数据

write(fd, data , strlen(data));

   

sleep(1);

 

int len = read(fd, recvBuf, sizeof(recvBuf));

if(len == -1) {

perror("read");

exit(-1);

} else if(len > 0) {

printf("recv server data : %s\n", recvBuf);

} else if(len == 0) {

// 表示服务器端断开连接

printf("server closed...");

break;

}

   

}

   

// 关闭连接

close(fd);

   

return 0;

}

 

posted @ 2022-09-16 19:12  atomxing  阅读(30)  评论(1编辑  收藏  举报