当前位置: 首页 > news >正文

Linux高阶——1117—TCP客户端服务端

目录

1、sock.h

socket常用函数

网络初始化函数

首次响应函数

测试IO处理函数

 获取时间函数

总代码

2、sock.c

SOCKET()

ACCEPT()——服务端使用这个函数等待客户端连接

 CONNECT()——客户端使用这个函数连接服务端

BIND()——一般只有服务端使用

LISTEN()——服务端使用

RECV()

SEND()

net_initializer()——网络初始化函数

get_time()——获取时间函数

first_response()——首次适应函数

总代码

3、生成网络动态库

客户端代码

服务端代码

成功截图


1、sock.h

socket常用函数

int ACCEPT(int,struct sockaddr*,socklen_t *); 
int SOCKET(int,int,int);
ssize_t RECV(int,void*,size_t,int);
int CONNECT(int, const struct sockaddr *,socklen_t);
int BIND(int, const struct sockaddr *,socklen_t);
int LISTEN(int, int backlog);
ssize_t SEND(int, const void *, size_t, int);

网络初始化函数

int net_initializer(const char*,int,int);

首次响应函数

int first_response(client_info);

测试IO处理函数

int test_business(int);

 获取时间函数

int get_time(char* tm);

总代码

#ifndef _MYSOCK_
#define _MYSOCK_
#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
#include<netdb.h>
#include<errno.h>
#include<time.h>
#include<stdio.h>
#endiftypedef struct
{int sockfd;int port;char ip[16];
}client_info;int ACCEPT(int,struct sockaddr*,socklen_t *); 
int SOCKET(int,int,int);
ssize_t RECV(int,void*,size_t,int);
int CONNECT(int, const struct sockaddr *,socklen_t);
int BIND(int, const struct sockaddr *,socklen_t);
int LISTEN(int, int backlog);
ssize_t SEND(int, const void *, size_t, int);int net_initializer(const char*,int,int);
int first_response(client_info);
int test_business(int);
int get_time(char* tm);

2、sock.c

SOCKET()

SOCKET(socket协议域,数据传输层使用协议模式,指定具体的协议)

int SOCKET(int domain,int type,int protocal)
{int fd; if((fd=socket(domain,type,protocal))==-1){perror("socket call failed");return fd; }   return fd; 
}

ACCEPT()——服务端使用这个函数等待客户端连接

ACCEPT(服务端socket,客户端的网络信息结构体,客户端网络信息结构体长度) ——客户端接收数据

int ACCEPT(int sockfd,struct sockaddr* addr,socklen_t * addrlen)
{int fd; if((fd=accept(sockfd,addr,addrlen))==-1){perror("accept call failed");return fd; }   return fd; 
}

 CONNECT()——客户端使用这个函数连接服务端

客户端只有一个socket

CONNECT(用于连接的socket,目标信息结构体,目标信息结构体长度)

int CONNECT(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
{int fd;if((fd=connect(sockfd,addr,addrlen))==-1){perror("connect call failed");return fd;}return fd;
}

BIND()——一般只有服务端使用

BIND(需要绑定的socket,网络信息结构体的地址,网络信息结构体的长度)

int BIND(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
{int fd;if((fd=bind(sockfd,addr,addrlen))==-1){perror("bind call failed");return fd;}return fd;
}

LISTEN()——服务端使用

LISTEN(服务端socket,等待连接队列的最大长度)

int LISTEN(int sockfd, int backlog)
{int fd;if((fd=listen(sockfd, backlog))==-1){perror("listen call failed");return fd;}return fd;
}

RECV()

RECV(套接字sockfd,数据buf,数据长度size,选项,发送的长度)

对于服务端,sockfd是accept函数的返回值

对于客户端,sockfd是connect函数的返回值

ssize_t RECV(int sockfd,void* buf,size_t len,int flag)
{ssize_t fd; if((fd=recv(sockfd,buf,len,flag))==-1){perror("recv call failed");return fd; }   return fd; 
}

SEND()

SEND(发送的人的sockfd,数据buf,数据包长度)

ssize_t SEND(int sockfd, const void *buf, size_t len, int flags)
{ssize_t fd;if((fd=send(sockfd,buf,len,flags))==-1){perror("send call failed");return fd;}return fd;
}

net_initializer()——网络初始化函数

net_initializer(ip地址,端口号,可以监听队列的最大长度)

int net_initializer(const char* ip,int port,int backlog)
{int sockfd;struct sockaddr_in addr;bzero(&addr,sizeof(addr));addr.sin_family=AF_INET;addr.sin_port=htons(port);addr.sin_addr.s_addr=inet_addr("82.157.31.74");sockfd=SOCKET(AF_INET,SOCK_STREAM,0);BIND(sockfd,(struct sockaddr*)&addr,sizeof(addr));LISTEN(sockfd,backlog);return sockfd;
}

get_time()——获取时间函数

get_time(时间数组)

int get_time(char* tm)
{bzero(tm,1024);time_t tp;tp=time(NULL);ctime_r(&tp,tm);tm[strlen(tm)-1]='\0';return 0;
}

first_response()——首次适应函数

first_response(定义的结构体)

client_info——定义的结构体——包含port,ip,和创建的套接字

typedef struct
{int sockfd;int port;char ip[16];
}client_info;
int first_response(client_info cf)
{char response[1500];bzero(response,1500);char tm[1024];get_time(tm);printf("Server,output info,client ip %s,client port %d\n",cf.ip,cf.port);SEND(cf.sockfd,response,strlen(response),MSG_NOSIGNAL);return 0;
}

总代码

#include<sock.h>int ACCEPT(int sockfd,struct sockaddr* addr,socklen_t * addrlen)
{int fd; if((fd=accept(sockfd,addr,addrlen))==-1){perror("accept call failed");return fd; }   return fd; 
}int SOCKET(int domain,int type,int protocal)
{int fd; if((fd=socket(domain,type,protocal))==-1){perror("socket call failed");return fd; }   return fd; 
}ssize_t RECV(int sockfd,void* buf,size_t len,int flag)
{ssize_t fd; if((fd=recv(sockfd,buf,len,flag))==-1){perror("recv call failed");return fd; }   return fd; 
}int CONNECT(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
{int fd;if((fd=connect(sockfd,addr,addrlen))==-1){perror("connect call failed");return fd;}return fd;
}int BIND(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
{int fd;if((fd=bind(sockfd,addr,addrlen))==-1){perror("bind call failed");return fd;}return fd;
}int LISTEN(int sockfd, int backlog)
{int fd;if((fd=listen(sockfd, backlog))==-1){perror("listen call failed");return fd;}return fd;
}ssize_t SEND(int sockfd, const void *buf, size_t len, int flags)
{ssize_t fd;if((fd=send(sockfd,buf,len,flags))==-1){perror("send call failed");return fd;}return fd;
}int net_initializer(const char* ip,int port,int backlog)
{int sockfd;struct sockaddr_in addr;bzero(&addr,sizeof(addr));addr.sin_family=AF_INET;addr.sin_port=htons(port);addr.sin_addr.s_addr=inet_addr("82.157.31.74");sockfd=SOCKET(AF_INET,SOCK_STREAM,0);BIND(sockfd,(struct sockaddr*)&addr,sizeof(addr));LISTEN(sockfd,backlog);return sockfd;
}int get_time(char* tm)
{bzero(tm,1024);time_t tp;tp=time(NULL);ctime_r(&tp,tm);tm[strlen(tm)-1]='\0';return 0;
}int first_response(client_info cf)
{char response[1500];bzero(response,1500);char tm[1024];get_time(tm);printf("Server,output info,client ip %s,client port %d\n",cf.ip,cf.port);SEND(cf.sockfd,response,strlen(response),MSG_NOSIGNAL);return 0;
}

3、生成网络动态库

将所有的.c或.cpp变成可重定位二进制文件(载入库数据时,查找可用内存,而不是固定地址)

生成可重定位的二进制文件.o——gcc test.c -fPIC -I头文件路径 -c

gcc sock.c -I./ -fPIC -c

生成.so库——gcc xxx.o -shared -fPIC -I头文件 -o libmysock.so

共享库名,线程库里为-lpthread,内存中为libpthread.so

gcc sock.o -shared -fPIC -I./ -o libmysock.so

生成库后,需要使用-L指定库位置——gcc x.c -I头文件 -L 库路径 -lmysock -o app

如果共享库已经在默认/usr/lib位置,编译时无需-L参数

查看程序所依赖的库文件,查看未加载成功的库名——ldd 程序名

ldd app

将共享库.so文件复制到/usr/lib/——mv libname.so /usr/lib/

在linux操作系统下,使用ifconfig命令查看本机私有ip地址,如果本机写服务器使用本机ip

成功后,可以直接使用./程序名运行程序

客户端代码

#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>#define server_ip "192.168.5.133"
#define server_port 9090int main()
{struct sockaddr_in client_addr;bzero(&client_addr,sizeof(client_addr));client_addr.sin_family = AF_INET;client_addr.sin_port = htons(server_port);client_addr.sin_addr.s_addr = inet_addr(server_ip);inet_pton(AF_INET,server_ip,&client_addr.sin_addr.s_addr);int client_sock;if((client_sock=socket(AF_INET,SOCK_STREAM,0))==-1){   perror("sock create failed");return -1; }   socklen_t addrlen;char recvv[1024];printf("TCP IO Client Running...\n");addrlen = sizeof(client_addr);if((connect(client_sock, (struct sockaddr*)&client_addr, addrlen))==-1){   perror("failed");return -1; }   bzero(recvv,sizeof(recvv));printf("client sock %d\n",client_sock);int len=recv(client_sock,recvv,sizeof(recvv),0);if(len==-1)perror("recv call failed");printf("len %d  %s\n",len, recvv);close(client_sock);
}

服务端代码

#include<sock.c>
#define server_ip "192.168.5.133"
#define server_port 9090int main()
{struct sockaddr_in client_addr;int server_sock;int client_sock;server_sock=net_initializer(NULL,server_port,128);socklen_t addrlen;printf("TCP IO Servers Running...\n");char cip[16];ssize_t len;client_info cf;char buf[1500];char* msg="Please try again\n";char tm[1024];while(1){addrlen=sizeof(client_addr);client_sock=ACCEPT(server_sock,(struct sockaddr*)&client_addr,&addrlen);cf.sockfd=client_sock;inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,cf.ip,16);cf.port=ntohs(client_addr.sin_port);first_response(cf);while((len=RECV(client_sock,buf,sizeof(buf),0))>0){if((strcmp(buf,"time\n"))==0){get_time(tm);SEND(client_sock,tm,strlen(tm),MSG_NOSIGNAL);bzero(tm,sizeof(tm));}else{SEND(client_sock,msg,strlen(msg),MSG_NOSIGNAL);}bzero(buf,sizeof(buf));}if(len==0){printf("client exit\n");close(client_sock);}}close(server_sock);printf("server done\n");return 0;
}

成功截图

http://www.lryc.cn/news/490644.html

相关文章:

  • 【Qt】Qt 在main.cpp中使用tr()函数报错
  • 面向对象高级(5)接口
  • uniapp发布android上架应用商店权限
  • Centos Stream 9安装Jenkins-2.485 构建自动化项目步骤
  • 电路模型和电路定理(二)
  • 瑞佑液晶控制芯片RA6807系列介绍 (三)软件代码详解 Part.10(让PNG图片动起来)完结篇
  • Qt常用控件 按钮
  • MySQL学习/复习10视图/用户/权限/语言连接数据库
  • vulfocus在线靶场:tomcat-pass-getshell 弱口令 速通手册
  • c#:winform调用bartender实现打印(学习整理笔记)
  • 牛客题库 21738 牛牛与数组
  • 探索PDFMiner:Python中的PDF解析利器
  • 掌握Go语言中的异常控制:panic、recover和defer的深度解析
  • 云讷科技Kerloud无人飞车专利发布
  • 企业信息化-走进身份管理之搭建篇
  • 实践指南:EdgeOne与HAI的梦幻联动
  • Exploring Prompt Engineering: A Systematic Review with SWOT Analysis
  • ByteBuffer 与 ByteBuf 的对比与优缺点分析
  • js高级06-ajax封装和跨域
  • RabbitMQ3:Java客户端快速入门
  • D 型 GaN HEMT 在功率转换方面的优势
  • Java Web后端项目的特点和组成部分
  • Vue3 + Vite + TS 项目引入 Eslint + Pritter
  • 用Tauri框架构建跨平台桌面应用:1、Tauri快速开始
  • Django实现智能问答助手-数据库方式读取问题和答案
  • stm32利用LED配置基础寄存器+体验滴答定时器+hal库环境配置
  • JAVA开源项目 桂林旅游景点导游平台 计算机毕业设计
  • docker安装使用Elasticsearch,解决启动后无法访问9200问题
  • GM、BP、LSTM时间预测预测代码
  • 《操作系统 - 清华大学》4 -5:非连续内存分配:页表一反向页表