客户端socket通信库
socket通信属于IO操作,因此客户端通常会将要发送的数据一次性发送至服务器,待服务器处理后然后返回结果信息给客户端。趁着离职期间比较闲,写了个客户端socket通信库,日后用得着的话就可以直接用。
目录中的文件有:compile.sh libnetcom.so netcom.c netcom.h
netcom.h文件内容有:
#ifndef _NETCOM_H_
#define _NETCOM_H_
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef struct st_socket_t
{
int socket;
char *recv_buff;
unsigned int cur_recv_index;
char *send_buff;
unsigned int cur_send_index;
unsigned int max_buff_len;
}st_socket_t;
int create_socket(st_socket_t **pp_socket);
int nc_conn(st_socket_t *p_socket, char *ip, int port);
int nc_get_one_byte(st_socket_t *p_socket, char *val);
int nc_get_n_byte(st_socket_t *p_socket, void *val, unsigned int n);
int nc_put_one_byte(st_socket_t *p_socket, char *val);
int nc_put_n_byte(st_socket_t *p_socket, void *val, unsigned int n);
int nc_send(st_socket_t *p_socket);
int nc_recv(st_socket_t *p_socket);
#endif
netcom.c文件内容有:
#include "netcom.h"
#define MAX_BUFF_LEN 8192
int create_socket(st_socket_t **pp_socket)
{
st_socket_t *p_socket = NULL;
p_socket = (st_socket_t *)malloc(sizeof(st_socket_t));
memset(p_socket, 0, sizeof(st_socket_t));
p_socket->socket = 0;
p_socket->max_buff_len = MAX_BUFF_LEN;
p_socket->recv_buff = (char *)malloc(sizeof(char) * MAX_BUFF_LEN);
memset(p_socket->recv_buff, 0, sizeof(char) * MAX_BUFF_LEN);
p_socket->send_buff = (char *)malloc(sizeof(char) * MAX_BUFF_LEN);
memset(p_socket->send_buff, 0, sizeof(char) * MAX_BUFF_LEN);
*pp_socket = p_socket;
return 0;
}
int nc_conn(st_socket_t *p_socket, char *ip, int port)
{
int ret = 0;
struct sockaddr_in sockaddr;
if (p_socket == NULL){
perror("p_socket == NULL");
}
p_socket->socket = socket(AF_INET, SOCK_STREAM, 0);
memset(&sockaddr, 0, sizeof(struct sockaddr_in));
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = inet_addr(ip);
sockaddr.sin_port = htons(port);
ret = connect(p_socket->socket, &sockaddr, sizeof(struct sockaddr_in));
return ret;
}
int nc_get_one_byte(st_socket_t *p_socket, char *val)
{
if (val == NULL){
return -1;
}
*val = p_socket->recv_buff[p_socket->cur_recv_index++];
return 0;
}
int nc_get_n_byte(st_socket_t *p_socket, void *val, unsigned int n)
{
int pos = p_socket->cur_recv_index;
if (val == NULL){
return -1;
}
memcpy(val, p_socket->recv_buff + pos, n);
p_socket->cur_recv_index += n;
return 0;
}
int nc_put_one_byte(st_socket_t *p_socket, char *val)
{
int ret = 0;
if (val == NULL){
return -1;
}
p_socket->send_buff[p_socket->cur_send_index++] = *val;
if (p_socket->cur_send_index == MAX_BUFF_LEN){
ret = send(p_socket->socket, p_socket->send_buff, MAX_BUFF_LEN, 0);
p_socket->cur_send_index = 0;
return ret;
}
return 0;
}
int nc_put_n_byte(st_socket_t *p_socket, void *val, unsigned int n)
{
int ret = 0;
int i = 0;
for (i = 0; i < n; i++){
ret = nc_put_one_byte(p_socket, &val[i]);
if (ret < 0){
return ret;
}
}
}
int nc_send(st_socket_t *p_socket)
{
return send(p_socket->socket, p_socket->send_buff, p_socket->cur_send_index, 0);
}
int nc_recv(st_socket_t *p_socket)
{
return recv(p_socket->socket, p_socket->recv_buff, p_socket->max_buff_len, 0);
}
编译连接之后生成libnetcom.so文件。
以上代码在健壮性方面仍有不足,并且有很多特殊情况都没有考虑,后续再补充。下面写一个测试用例,测试库文件的基本功能。
服务器端测试文件server.c:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#define SERVER_PORT 6000
#define BUFF_LEN 1024
int main(int argc, char *argv[])
{
int sock = 0, acc_sock = 0;
struct sockaddr_in sockaddr, acc_sock_addr;
int ret = 0;
sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&sockaddr, 0, sizeof(struct sockaddr_in));
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = INADDR_ANY;
sockaddr.sin_port = htons(SERVER_PORT);
ret = bind(sock,&sockaddr, sizeof(struct sockaddr_in));
if (ret < 0){
fprintf(stderr, "bind error--%s\n", strerror(errno));
exit(-1);
}
ret = listen(sock, 10);
if (ret < 0){
fprintf(stderr, "listen error--%s\n", strerror(errno));
exit(-1);
}
while (1)
{
socklen_t acc_addr_len = 0;
char buff[BUFF_LEN] = {0}, send_buff[BUFF_LEN] = {0};
acc_sock = accept(sock, &acc_sock_addr, &acc_addr_len);
if (acc_sock < 0){
fprintf(stdout, "accept error--%d\n", errno);
exit(-1);
}
printf("%s:%d connect to server\n", inet_ntoa(acc_sock_addr.sin_addr), acc_sock_addr.sin_port);
ret = recv(acc_sock, buff, sizeof(buff), 0);
sprintf(send_buff, "echo %s, %d", buff, ret);
ret = send(acc_sock, send_buff, strlen(send_buff), 0);
printf("send %d byte:%s\n", ret, send_buff);
}
return 0;
}
客户端测试文件client.c
#include "netcom/netcom.h"
#define IP "192.168.1.91"
#define PORT 6000
int main()
{
int ret = 0;
st_socket_t *p_socket = NULL;
char buff[] = "hello";
char ch = 0;
char recv_buff[1024] = "";
create_socket(&p_socket);
ret = nc_conn(p_socket, IP, PORT);
if (ret < 0){
perror("nc_conn");
exit(-1);
}
ret = nc_put_one_byte(p_socket, buff);
strcpy(buff, "good");
ret = nc_put_n_byte(p_socket, buff, strlen(buff));
ret = nc_send(p_socket);
ret = nc_recv(p_socket);
printf("recv %d byte\n", ret);
ret = nc_get_one_byte(p_socket, &ch);
printf("ch = %c\n", ch);
ret = nc_get_n_byte(p_socket, recv_buff, 10);
printf("recv_buff = %s\n", recv_buff);
return 0;
}
先执行服务器端,然后执行客户端之后:
[root@localhost echo]# ./server
255.127.0.0:60710 connect to server
send 13 byte:echo hgood, 5
root@szty-ThinkCentre-XXXX:lming_08# ./client
recv 13 byte
ch = e
recv_buff = cho hgood,
可以看出测试的效果还是不错的。
客户端socket通信库相关推荐
- python安卓开发实例_python服务器与android客户端socket通信实例
本文实例讲述了python服务器与android客户端socket通信的方法.分享给大家供大家参考.具体实现方法如下: 首先,服务器端使用python完成,下面为python代码: #server.p ...
- android 手机 与 python服务器_python服务器与android客户端socket通信实例
本文实例讲述了python服务器与android客户端socket通信的方法.分享给大家供大家参考.具体实现方法如下: 首先,服务器端使用python完成,下面为python代码: #server.p ...
- 多路双向串口转网口上位机C++源代码带主动连接支持UDP和TCP客户端Socket通信C语言
多路双向串口转网口上位机C++源代码带主动连接支持UDP和TCP客户端Socket通信C语言 使用说明介绍 1.功能介绍: 完成了多路网口和串口数据转换的功能. 可实现串口接收到的数据,通过网口发送出 ...
- 基于Java的RDMA高性能通信库(二):Java Socket Over RDMA
目录 1.Comparing JSOR with Java TCP communications 2.Comparing JSOR to Java Sockets Direct Protocol (S ...
- 【学习笔记】在windows下进行基于TCP的本地客户端和服务端socket通信
文章目录 socket介绍 java中使用socket 基于tcp的socket通信 使用ServerSocket类创建一个web服务器:(java) windows下的基于tcp的socket编程( ...
- Socket代码实现服务端 和 客户端之间通信
服务端代码 // Socket_connection.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #ifndef UNICODE #define ...
- 【游戏开发实战】用Go语言写一个服务器,实现与Unity客户端通信(Golang | Unity | Socket | 通信 | 教程 | 附工程源码)
文章目录 一.前言 二.Go开发环境搭建(Windows系统) 1.安装Go命令行工具 2.创建GoWorkspace目录 3.配置GOPATH环境变量 4.配置GOPROXY代理 5.安装VSCod ...
- python 实现TCP socket通信和 HTTP服务器、服务器和客户端通信python实例
python 实现TCP socket通信和 HTTP服务器.服务器和客户端通信实例 socket是什么? 服务器和客户端通信的流程 python 实现TCP socket通信例子 关于Host和PO ...
- java iso8583 socket 服务_JAVA客户端amp;服务器的socket通信
JAVA客户端&服务器的socket通信 socket是两台主机之间的一个连接通道,它可以完成七个基本操作: 发送远程机器 发送数据 接收数据 关闭连接 绑定端口 监听入站数据 再绑定端口上接 ...
最新文章
- 双色球随机选号器界面设计及功能实现
- JNDI数据源的使用
- SharePoint WebPart:扩展SharePoint 2007中图片展示功能
- tomcat(9)Session管理
- 网站后端_Python+Flask.0007.FLASK构造跳转之301跳转与302重定向?
- vue 根据for循环变量值设置子容器的样式
- Windows下MySql主从配置实战教程
- PopupWindow正确使用方式
- C专家编程--随记(二)
- 从《目标》、《凤凰项目》到《持续交付》:DevOps 的过去、现在及未来 | Chat · 预告
- React使用ECharts
- Linux常用图片查看处理软件
- 硬盘容量的计算方法,这就是为什么实际容量总比官方标示少的原因
- 聚焦云+人工智能,纳德拉宣布微软重大重组
- 大学四年生活总结_2020校园寝室生活必备好物推荐,大学四年,留下点回忆,好不啦...
- android显示输入法键盘布局,android 解决输入法键盘遮盖布局问题
- 2017第九届北京空气净化及水净化、北京国际节能减排展览会会刊
- win10桌面频繁刷新
- 网站为什么会被降权?如何恢复网站被降权,没有流量呢?
- 一个猜灯谜的游戏(求解)
热门文章
- 解决 Windows Defender might be impacting your build performance. PyCharm checked the following directo
- php数据库自动引蜘蛛,SEO之小旋风万能站群池X5.1去限制版,引蜘蛛提高排名,免授权永久使用...
- Linux查看内存型号,插槽使用情况,内存频率,内存制造商等信息
- 怎么让自己平静下来!
- K8s 支持一键部署
- 小米笔记本安装android系统下载失败,小米平板电脑2如果刷成安卓的系统失败了怎么处理...
- Win8下如何安装Win7 or Win7下如何安装win8?
- mex matlab混编,Matlab中mex与C混合编程总结
- Python-urllib2的使用
- 企业中多分支多人协作的git工作流程