Linux环境下实现实现简单 TCP通信demo。
例程一:client端和serve端相互发送接收,打印接收到的内容即退出结束。这里使用的IP地址是本机环回地址“127.0.0.1”,只能进行本地通信。
1 localhost、127.0.0.1和0.0.0.0和本机IP的区别 2 localhost 3 localhost其实是域名,一般windows系统默认将localhost指向127.0.0.1,但是localhost并不等于127.0.0.1,localhost指向的IP地址是可以配置的 4 5 127.0.0.1 6 首先我们要先知道一个概念,凡是以127开头的IP地址,都是回环地址(Loop back address),其所在的回环接口一般被理解为虚拟网卡,并不是真正的路由器接口。 7 8 所谓的回环地址,通俗的讲,就是我们在主机上发送给127开头的IP地址的数据包会被发送的主机自己接收,根本传不出去,外部设备也无法通过回环地址访问到本机。 9 10 小说明:正常的数据包会从IP层进入链路层,然后发送到网络上;而给回环地址发送数据包,数据包会直接被发送主机的IP层获取,后面就没有链路层他们啥事了。 11 12 而127.0.0.1作为{127}集合中的一员,当然也是个回环地址。只不过127.0.0.1经常被默认配置为localhost的IP地址。 13 一般会通过ping 127.0.0.1来测试某台机器上的网络设备是否工作正常。 14 15 0.0.0.0 16 首先,0.0.0.0是不能被ping通的。在服务器中,0.0.0.0并不是一个真实的的IP地址,它表示本机中所有的IPV4地址。监听0.0.0.0的端口,就是监听本机中所有IP的端口。 17 18 本机IP 19 本机IP通常仅指在同一个局域网内,能同时被外部设备访问和本机访问的那些IP地址(可能不止一个)。像127.0.0.1这种一般是不被当作本机IP的。本机IP是与具体的网络接口绑定的,比如以太网卡、无线网卡或者PPP/PPPoE拨号网络的虚拟网卡,想要正常工作都要绑定一个地址,否则其他设备就不知道如何访问它 20 21 22 链接:https://www.jianshu.com/p/ad7cd1d5be45
代码如下:
client code:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> int main(){ //创建套接字 int sock = socket(AF_INET, SOCK_STREAM, 0); //向服务器(特定的IP和端口)发起请求 struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充 serv_addr.sin_family = AF_INET; //使用IPv4地址 serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址 serv_addr.sin_port = htons(1234); //端口 while (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) { sleep(1); printf("wait serve "); } //读取服务器传回的数据 char buffer[40]; read(sock, buffer, sizeof(buffer)-1); printf("Message form server: %s ", buffer); //向serve端发送数据 char str[] = "Hello!"; int count = 0, err; while ((err = write(sock, str, sizeof(str))) <= 0 && count++ < 10) { printf("wait %d ", err); sleep(1); } //关闭套接字 close(sock); return 0; }
serve code:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> int main(){ //创建套接字 int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //将套接字和IP、端口绑定 struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充 serv_addr.sin_family = AF_INET; //使用IPv4地址 serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址 serv_addr.sin_port = htons(1234); //端口 bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); //进入监听状态,等待用户发起请求 listen(serv_sock, 20); printf("监听结束 "); //接收客户端请求 struct sockaddr_in clnt_addr; socklen_t clnt_addr_size = sizeof(clnt_addr); int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size); //向客户端发送数据 char str[] = "Hello World!"; write(clnt_sock, str, sizeof(str)); //读取client传回的数据 char buffer[40]; int err, count = 0; while ( (err = read(clnt_sock, buffer, sizeof(buffer)-1)) <= 0 && count++ < 10) { printf("wait %d ", err); sleep(1); } printf("Message form client: %s ", buffer); //关闭套接字 close(clnt_sock); close(serv_sock); return 0; }
运行演示效果:
例程二:client和serve都创建一个线程进行获取输入和发送输入内容,原来主线程会将接收到的内容打印出来,当输入内容或则接收内容为“bye”时将退出程序运行。这里serve是运行在IP地址为"172.16.194.184"的虚拟机上,所以client和serve的对应代码需要修改serve的IP地址。I
IP地址的查看方法:输入ifconfig指令:
代码如下:
client code:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <arpa/inet.h> 6 #include <sys/socket.h> 7 #include <pthread.h> 8 9 10 int getchar_input_str(char * input_buff); 11 12 int g_flag_exit = 0; 13 char input_str[100], read_buff[100]; 14 int clnt_sock_fd; 15 16 17 18 void * TCP_send(void *arg) 19 { 20 int input_count = 0; 21 22 while(1) { 23 printf("self:"); 24 input_count = getchar_input_str(input_str); 25 send(clnt_sock_fd, input_str, input_count + 1, 0); 26 27 //printf("client:[%d] %s ", input_count, input_str); 28 if (input_str[0] == 'b' && input_str[1] == 'y' && input_str[2] == 'e') { 29 g_flag_exit = 1; 30 31 return NULL; 32 } 33 } 34 35 } 36 37 38 39 int main() 40 { 41 42 //创建套接字 43 clnt_sock_fd = socket(AF_INET, SOCK_STREAM, 0); 44 45 //向服务器(特定的IP和端口)发起请求 46 struct sockaddr_in serv_addr; 47 memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充 48 serv_addr.sin_family = AF_INET; //使用IPv4地址 49 serv_addr.sin_addr.s_addr = inet_addr("172.16.194.184"); //具体的IP地址 50 serv_addr.sin_port = htons(1234); //端口 51 52 53 54 while (connect(clnt_sock_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) { 55 sleep(1); 56 printf("wait serve connect "); 57 } 58 59 pthread_t tid; 60 pthread_create(&tid, NULL, TCP_send, "TCP_send"); 61 62 while(1) { 63 64 recv(clnt_sock_fd, read_buff, sizeof(read_buff)-1, 0); 65 printf("