TA的每日心情 | 开心 2022-8-16 09:50 |
---|
签到天数: 16 天 连续签到: 1 天 [LV.4]偶尔看看III
|
在这个网络的时代,什么东西都想着上网,智能产品的核心就是网络通讯,这段时间学习了下linux下的网路编程,用香蕉派做了一个tcpserver先调 试调试,后期再实现其他功能,先把路打通,要想富先修路嘛,先实现基本的tcp通讯。
香蕉派操作的相关在我之前的经验里有。这里就说下linux下网络的编程。
linux下的网络的编程简单来讲就是对socket的操作,其实我们应用的话不用管socket是什么鬼,就把它当文件来对待(读/写IO、打开、关闭和文件操作一样),毕竟linux下一切皆文件嘛。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
1socket函数原型int socket(int domain, int type, int protocol);
domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
type:指定socket类型。常用的socket类型有,流式SOCK_STREAM、数据报式SOCK_DGRAM、原始套接字SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等(socket的类型有哪些?)。
protocol:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
2bind()
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
bind()所做的事情其实就是: 将该socket和本地的IP地址和某个端口号相关联 -- 将sockaddr与socket绑定
参数一 sockfd:即socket描述字,它是通过socket()函数创建了,唯一标识一个socket。bind()函数就是将给这个描述字绑定一个地址。
参数二 addr:一个const struct sockaddr *指针,指向要绑定给sockfd的协议地址。这个地址结构根据地址创建socket时的地址协议族的不同而不同,
参数三 addrlen:对应的是地址的长度,设置成sizeof(struct sockaddr)
3
如果作为一个服务器,在调用socket()、bind()之后就要调用listen()来监听这个socket,如果客户端这时调用connect()发出连接请求,服务器端就会接收到这个请求。
int listen(int sockfd, int backlog);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
connect函数的第一个参数即为客户端的socket描述字,第二参数为服务器的socket地址,即远端主机IP地址和端口号的指针,第三个参数为socket地址的长度。客户端通过调用connect函数来建立与TCP服务器的连接。
4.accept()
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
函数让服务器接收客户的连接请求。在建立好输入队列后,服务器就调用accept函数,然后睡眠并等待客户的连接请求
如果accpet成功,那么其返回值是由内核自动生成的一个全新的描述字,代表与返回客户的TCP连接。
5. read()write()
accpet返回成功表示路已经通了,就可以通讯了,和对文件读写一样的操作,是不是很方便
6.close()
在服务器与客户端建立连接之后,会进行一些读写操作,完成了读写操作就要关闭相应的socket描述字,好比操作完打开的文件要调用fclose关闭打开的文件,这样就不能再对此套接口做任何的读写操作了。
以下是我测试tcp连接用的程序,还只是实现一个tcp server的功能,能实现发送什么回复什么,还只是单个客户端1对1的模式,下次再讲1对多的情况,需要一些进程操作。还在了解中。现附上程序如下
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>int main(int argc, char *argv[]){ int broadcast=1; int serv_sock; int clnt_sock; int cnt = 0; struct sockaddr_in serv_addr; struct sockaddr_in clnt_addr; socklen_t clnt_addr_size; char message[] = "ai ban wang lx"; char buff[256] = {0}; serv_sock = socket(AF_INET, SOCK_STREAM, 0); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(8888); bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); setsockopt(serv_sock,SOL_SOCKET,SO_BROADCAST,&broadcast, sizeof(int)); listen(serv_sock, 5); clnt_addr_size = sizeof(clnt_addr); clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size); write(clnt_sock, message, sizeof(message)); // write(0,"lx online",250); while(1) { cnt = read(0,buff,256); write(clnt_sock, buff, cnt); // cnt=read(clnt_sock,buff,256); // write(0,buff,cnt); } close(clnt_sock); close(serv_sock); return 0;}我们可以在记事本或者note++中编写程序,然后通过ftp的方式传到香蕉派上,见我上篇经验https://jingyan.eeboard.com/article/75832
然后找到我们的程序文件编译即可
最后我们用一个tcp测试的工具来测试 端口8888ip以香蕉派的ip为准(ifconfig)
连接成功后服务器会回复你一条消息 ai ban wang lx然后你还可以继续发送服务器内容,发送什么回复什么。
我的tcp测试工具链接:https://pan.baidu.com/s/1nuD4fyT 密码:qhf5 |
|