Linux 网络编程--socket通信

手里的智能锁项目, 最新要新加一个功能,就是通过无线把锁里的开门记录,登记人员这些信息发送出去 ,板子SDK本身是带有WIFI功能的 , 所以我需要实现的功能就两点, 首先 , 把设备(智能锁)连接上WIFI,  第二 , 把数据通过tcp/ip应用层协议的socket协议发送出去 , 就可以了。

我这里讲一下步骤吧 , 首先 , 我电脑端开了一个sockettools监听 , 第二, 配置我板子的ssid以及psk(WiFi账号和密码),第三写一个socket的client的通信实例把数据发送出去。

由于没有用到多线程, socket通信应该算是比较简单的, 分以下几个步骤吧

1 : socket()建立一个套接字, 类似open打开一个文件

2 : 填充struct sockaddr_in结构体, 分别填充sin_family字段, sin_port字段, sin_addr.s_addr字段

3 : connect目标服务器

4 : recv/send

5:close()

好了, 话不多说 , 直接上代码

client.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>



#define PORT 12333                //服务器端口号
#define SERVERIP "192.168.1.80"    //服务器IP地址


//客户端
int main(int argc, char **argv)
{
	int sd; //文件描述符
	int ret;

	//1 创建套接字
	sd = socket(AF_INET, SOCK_STREAM, 0); 
	if (sd == -1) {
		printf("socket failed!\n");
		return -1;
	}

	printf("socket success!\n");

	// 2 填充struct sockaddr_in结构体
	struct sockaddr_in dest;
	dest.sin_family = AF_INET;
	dest.sin_port = htons(PORT);
	dest.sin_addr.s_addr = inet_addr(SERVERIP);

	// 3 connect
	ret = connect(sd, (struct sockaddr *)&dest, sizeof(dest));
	if (ret == -1) {
		printf("connect failed!\n");
		close(sd);
		return -1;
	} else {
		printf("connect success !\n");
	}

	// 4 发送数据
	char *send_buf = "this is ilock x1000 test ...";
	int send_len = strlen(send_buf);
	ret = send(sd, send_buf, send_len, 0);
	if (ret == -1) {
		printf("send failed!\n");
		return -1;
	} else {
		printf("send success \n");
	}
	printf("ret = %d\n", ret);
	//5 关闭套接字
	char read_buf[128] = {0};
	while(read(sd, read_buf, sizeof(read_buf)) < 0);
	close(sd);
	return 0;
}

服务端的代码也上一份 , 其实很客户端也比较类似 , 只是说第三步connect()改成listen()之后accept()

server.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <syspes.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>

#define PORT 12333

#define BACKLOG 5
int main(void)
{
	int socketfd, new_fd; 
	int ret, sock_len;
	struct sockaddr_in dest_addr, addr_in;
	
	// 1 建立socket
	socketfd = socket(AF_INET, SOCK_STREAM, 0);
	if (socketfd == -1) {
		perror("socket failed");
		goto out;
	}

	// 2 填充struct sockaddr_in 结构体
	addr_in.sin_family = AF_INET;
	addr_in.sin_port = htons(PORT);
	addr_in.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY宏展开为0.0.0.0, 如果服务端在这个地址上监听, 此时会监听服务器上所有的网卡。

	// 3 绑定socketfd和addr_in结构体
	ret = bind(socketfd, (struct sockaddr *)&addr_in, sizeof(addr_in));
	if (ret < 0) {
		perror("bind error !\n");
		goto err;
	}
	// 4 按照addr_in结构体的配置 , 进行监听
	listen(socketfd, BACKLOG);
	printf("listening ...\n");

	char buf[128] = {0};
	while (1) {
		sock_len = sizeof(struct sockaddr_in);
		// 5 建立连接 
		new_fd = accept(socketfd, (struct sockaddr *)&dest_addr, &sock_len); 
		if (new_fd == -1) { 
			printf("accept error !\n");
		} else {//此时连接成功
			ret = recv(new_fd, buf, sizeof(buf), 0);
			if (ret < 0) {
				printf("recv error !\n");
			} else {
				printf("recv : %s \n", buf); //处理接收到的数据,我这里用最简单的打印的方式
			}
			if (strstr(buf, "x1000") != NULL) { //如果发送的字符串中包含有"x1000" 的话break出循环
				close(new_fd);
				break;
			}
		}
	}
	// 5 close()
	close(socketfd);
	return 0;
err:
	return ret;
out:
	return -1;
}

这里多补充一点 INADDR_ANY这个宏

它是用于多IP机器上   
    
  比如你的机器有三个ip   
  192.168.1.80
  222.222.222.222
  61.1.2.5
  如果你serv.sin_addr.s_addr=inet_addr("192.168.1.80");   
    
  然后监听100端口   
    
  这时其他机器只有connect   192.168.1.80:100才能成功。
  connect   222.222.222.222:100和connect   61.1.2.5:100都会失败。   
    
  如果serv.sin_addr.s_addr=htonl(INADDR_ANY);   的话,无论连接哪个ip都可以连上的。

猜你喜欢

转载自blog.csdn.net/weixin_38176039/article/details/81505457