-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnet_sockets.c
1350 lines (1171 loc) · 34.1 KB
/
net_sockets.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sched.h>
//#include <netinet/in.h>
//#include <arpa/inet.h>
#include <unistd.h>
//#include <sys/socket.h>
#include <netdb.h>
#include "net_sockets.h"
/****************************************************************************************
* static
****************************************************************************************/
static int rpt_lvl = 2; /* report level: ERR, WRN, INF, DBG */
static SOCK_PARAM sock_params_default =
{
SOCK_AF_IPv4,
SOCK_UDP_DGRAM,
SOCK_PROTO_UDP,
SOCK_DEFAULT_IP,
SOCK_DEFAULT_PORT,
0,
0,
};
/****************************************************************************************
* Define
****************************************************************************************/
/* report level */
#define RPT_ERR (1) // error, system error
#define RPT_WRN (2) // warning, maybe wrong, maybe OK
#define RPT_INF (3) // important information
#define RPT_DBG (4) // debug information
/* report micro */
#define RPT(lvl, ...) \
do { \
if(lvl <= rpt_lvl) { \
switch(lvl) { \
case RPT_ERR: \
fprintf(stderr, "\"%s\" line %d [err]: ", __FILE__, __LINE__); \
break; \
case RPT_WRN: \
fprintf(stderr, "\"%s\" line %d [wrn]: ", __FILE__, __LINE__); \
break; \
case RPT_INF: \
fprintf(stderr, "\"%s\" line %d [inf]: ", __FILE__, __LINE__); \
break; \
case RPT_DBG: \
fprintf(stderr, "\"%s\" line %d [dbg]: ", __FILE__, __LINE__); \
break; \
default: \
fprintf(stderr, "\"%s\" line %d [???]: ", __FILE__, __LINE__); \
break; \
} \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} \
} while(0)
#ifndef OFFSET
#define OFFSET(structure, member) ((int) &(((structure *) 0) -> member))
#endif
#ifndef false
#define false 0
#endif
#ifndef true
#define true 1
#endif
#ifndef NULL
#define NULL 0
#endif
#define SOCK_TSK_STACK_SIZE 10*1024
#define MAX_CONNECT_NUM SOMAXCONN
/****************************************************************************************
* Function
****************************************************************************************/
/*****************************************************************************************
* 函数名称: NetToTextStr
* 函数功能: 网络字节序的二进制IP地址转化成 点分十进制字符串
* 输入参数: AddrFamily: 需转换的地址的类型,IPv4 IPv6
addr : 网络字节序的二进制IP地址
NameZize : 点分十进制地址字符串大小
* 输出参数: AddrName : 指向转换后点分十进制地址字符串;大小由NameZize指定
* 返回结果: -1:转换失败;0:转换成功
* 修改记录:
******************************************************************************************/
int NetToTextStr(int AddrFamily, unsigned int addr,char *AddrName,int NameZize)
{
char ret = 0;
if(AddrName == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
if(inet_ntop(AddrFamily,&addr,AddrName,NameZize) == NULL)
{
ret = -1;
}
return ret;
}
/*****************************************************************************************
* 函数名称: TextStrToNet
* 函数功能: 点分十进制字符串转化成二进制IP地址网络字节序
* 输入参数:
* 输出参数:
* 返回结果: 成功返回1;未被格式化为有效地址返回0;指定的地址族未知返回-1
* 修改记录:
******************************************************************************************/
int TextStrToNet(int AddrFamily,char *AddrName,unsigned int* addr)
{
char ret = 0;
if(AddrName == NULL || addr == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
ret = inet_pton(AddrFamily,AddrName,addr);
return ret;
}
/*****************************************************************************************
* 函数名称: sock_print_addr
* 函数功能: 打印IP地址与端口号
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
int sock_print_addr(struct sockaddr *Addr,char *RptStr)
{
char ret = 0;
struct sockaddr_in *pCAddr;
char AddrName[50] = {0};
int AddrF = 0;
if(Addr == NULL || RptStr == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
pCAddr = (struct sockaddr_in *)Addr;
AddrF = pCAddr->sin_family;
ret = NetToTextStr(AddrF,pCAddr->sin_addr.s_addr,AddrName,sizeof(AddrName));
if (ret != -1)
{
RPT(RPT_WRN,"%s %s/%d",RptStr,AddrName,ntohs(pCAddr->sin_port));
}
return ret;
}
/*****************************************************************************************
* 函数名称: sock_close
* 函数功能: 关闭套接字
* 输入参数:
* 输出参数: 无
* 返回结果: 无
* 修改记录:
******************************************************************************************/
static void sock_close(int socket_fd)
{
if(socket_fd > 0)
close(socket_fd);
}
/*****************************************************************************************
* 函数名称: sock_create
* 函数功能: 创建套接字
* 输入参数: AddrFamily:地址类型,其值可为SOCK_AF_IPv4、SOCK_AF_IPv6等
SockType :套接字类型,其值可为SOCK_UDP_DGRAM、SOCK_TCP_STREAM等
SockProto :协议,其值可为SOCK_PROTO_TCP、SOCK_PROTO_UDP等
* 输出参数: 无
* 返回结果: 创建成功返回套接字描述符;否则返回-1
* 修改记录:
******************************************************************************************/
static int sock_create(int AddrFamily,int SockType,int SockProto)
{
int socket_fd = -1;
socket_fd = socket(AddrFamily,SockType, SockProto);
return socket_fd;
}
/*****************************************************************************************
* 函数名称: sock_bind
* 函数功能: 将套接字与服务器地址绑定
* 输入参数: SockFd : 套接字描述符
ServAddr :指向服务器的一个地址,包含IP地址与端口
* 输出参数: 无
* 返回结果: 绑定成功返回0;失败返回-1
* 修改记录:
******************************************************************************************/
static int sock_bind(int SockFd,struct addrinfo* ServAddr)
{
int ret = 0;
if(ServAddr == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
ret = bind(SockFd,ServAddr->ai_addr,ServAddr->ai_addrlen);
return ret;
}
/*****************************************************************************************
* 函数名称: sock_listen
* 函数功能: 实现侦听来自客户的连接请求
* 输入参数:
* 输出参数:
* 返回结果: 成功 0;失败 -1
* 修改记录:
******************************************************************************************/
static int sock_listen(int SockFd)
{
int ret = 0;
ret = listen(SockFd,MAX_CONNECT_NUM);
return ret;
}
/*****************************************************************************************
* 函数名称: sock_accept
* 函数功能: 获得连接请求并建立连接
* 输入参数:
* 输出参数:
* 返回结果: 成功返回套接字描述符;失败返回-1
* 修改记录:
******************************************************************************************/
static int sock_accept(int SockFd)
{
int ClntSock = 0;
socklen_t clntLen;
struct sockaddr clntAddr;
clntLen = sizeof(clntAddr);
ClntSock = accept(SockFd,&clntAddr, &clntLen);
if (ClntSock < 0)
{
return -1;
}
sock_print_addr(&clntAddr,"client addr ");
return ClntSock;
}
/*****************************************************************************************
* 函数名称: sock_recv
* 函数功能: 接收数据
* 输入参数: SockFd:套接字描述符;size:此次可接收的最大字节数;
flags:改变套接字调用的默认行为的某些方面,一般为0
* 输出参数: buff :指向接收数据的存储空间
* 返回结果: 接收成功返回此次接收的数据大小;失败返回-1
* 修改记录:
******************************************************************************************/
static int sock_recv(int SockFd,void *buff,int size,int flags)
{
int RecvSize = 0;
if(buff == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
RecvSize = recv(SockFd,buff,size,flags);
return RecvSize;
}
/*****************************************************************************************
* 函数名称: sock_recv_from_clntAddr
* 函数功能: 从指定地址的客户端接收数据
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_recv_from_clntAddr(int SockFd,void *buff,int size,int flags,
struct sockaddr *ClntAddr,socklen_t *ClntAddrLen)
{
int ret = 0;
if(buff == NULL || ClntAddr == NULL ||ClntAddrLen == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
ret = recvfrom(SockFd,buff,size,flags,ClntAddr,ClntAddrLen);
return ret;
}
/*****************************************************************************************
* 函数名称: sock_send
* 函数功能: 发送数据
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_send(int SockFd,void *buff,int size,int flags)
{
int RecvSize = 0;
if(buff == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
RecvSize = send(SockFd,buff,size,flags);
return RecvSize;
}
/*****************************************************************************************
* 函数名称: sock_send_to_clntAddr
* 函数功能: 发送到指定地址的客户端
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_send_to_clntAddr(int SockFd,void *buff,int size,int flags,
struct sockaddr *ClntAddr,socklen_t ClntAddrLen)
{
int ret = 0;
if(buff == NULL ||ClntAddr == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
ret = sendto(SockFd,buff,size,flags,ClntAddr,ClntAddrLen);
return ret;
}
/*****************************************************************************************
* 函数名称: sock_option_set
* 函数功能: 设置套接字选项
* 输入参数:
* 输出参数:
* 返回结果: 成功返回0;出错返回-1
* 修改记录:
******************************************************************************************/
static int sock_option_set(int SockFd,int level,int opt,void* val,socklen_t optLen)
{
int ret = 0;
if(val == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
ret = setsockopt(SockFd,level,opt,val,optLen);
return ret;
}
/*****************************************************************************************
* 函数名称: sock_option_get
* 函数功能: 查询某个套接字选项状态
* 输入参数:
* 输出参数:
* 返回结果: 成功返回0;出错返回-1
* 修改记录:
******************************************************************************************/
static int sock_option_get(int SockFd,int level,int opt,void* val,socklen_t *optLen)
{
int ret = 0;
if(val == NULL ||optLen == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
ret = getsockopt(SockFd,level,opt,val,optLen);
return ret;
}
/*****************************************************************************************
* 函数名称: sock_opt_list_set
* 函数功能: 初始化各套接字选项属性
* 输入参数:
* 输出参数:
* 返回结果: 成功返回0;出错返回-1
* 修改记录:
******************************************************************************************/
static int sock_opt_list_set(SOCK_OBJ *h,int sock_fd)
{
int ret = 0;
int i = 0;
SOCK_OPT *pSockOpt = NULL;
int OptNum = 0;
if(h == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
RPT(RPT_WRN, "socket opt set start");
OptNum = h->CurrOptNum;
for (i = 0;i < OptNum;i++)
{
pSockOpt = &(h->opt[i]);
if (pSockOpt->flag == 0x5a)
{
ret = sock_option_set(sock_fd,pSockOpt->level,pSockOpt->optName,
pSockOpt->val,pSockOpt->optLen);
if (ret < 0)
{
RPT(RPT_ERR, "socket opt set (%s) fail",pSockOpt->optStr);
break;
}
RPT(RPT_WRN, "socket opt set (%s) success",pSockOpt->optStr);
}
}
return ret;
}
/*****************************************************************************************
* 函数名称: sock_is_ready
* 函数功能: 描述符是否已经准备好
* 输入参数: socket_fd:套接字描述符,timeout:超时控制时间值
* 输出参数: 无
* 返回结果: 准备就绪的描述符数目,超时返回0,出错返回-1
* 修改记录:
******************************************************************************************/
static int sock_is_ready(int socket_fd, uint32_t timeout/*ms*/)
{
fd_set fdset;
int ret = 0;
struct timeval timeval;
memset(&timeval, 0, sizeof(struct timeval));
timeval.tv_sec = timeout / 1000;
timeval.tv_usec = (timeout % 1000) * 1000;
//将fdset所有位均置为0(描述符状态清零)
FD_ZERO(&fdset);
//将socket_fd描述符位置1
FD_SET(socket_fd, &fdset);
//描述符是否可读
ret = select(socket_fd + 1, &fdset, NULL, NULL, &timeval);
if(ret < 0)
{
RPT(RPT_ERR, "socket_fd select error");
return -1;
}
else if (ret == 0)
{
RPT(RPT_ERR, "socket_fd select not ready");
return 0;
}
//测试描述符是否仍旧设置
if(FD_ISSET(socket_fd, &fdset) == 0)
{
RPT(RPT_ERR, "socket_fd not set");
return 0;
}
return ret;
}
/*****************************************************************************************
* 函数名称: sock_snd_flag_set
* 函数功能: 数据是否解析完成并准备发送的标志
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
void sock_snd_flag_set(sockets_handle h,char state)
{
SOCK_OBJ *handle = h;
pthread_mutex_lock(&handle->mux);
handle->sock_snd_flag = state;
pthread_mutex_unlock(&(handle->mux));
}
/*****************************************************************************************
* 函数名称: sock_snd_flag_get
* 函数功能: 查询发送数据是否完成的标志
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
char sock_snd_flag_get(sockets_handle h)
{
SOCK_OBJ *handle = h;
char state = 0;
state = handle->sock_snd_flag ;
return state;
}
/*****************************************************************************************
* 函数名称: sock_addr_list_get
* 函数功能: 服务器地址列表的获取;允许将一个主机和服务名字映射到一个地址
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_addr_list_get(SOCK_PARAM* SocketParam,struct addrinfo** AddrList)
{
int ret = 0;
char PortStr[10] = {0};
char LocalAddr[50] = {0};
unsigned int LocalIPNet = 0;
struct addrinfo HintAddr;
memset(&HintAddr,0,sizeof(HintAddr));
if(SocketParam == NULL || AddrList == NULL || *AddrList == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
//端口号字符串
sprintf(PortStr,"%d",SocketParam->port);
//ip地址字符串格式
LocalIPNet = htonl(SocketParam->AddrIP);
if (NetToTextStr(SocketParam->addr_family,LocalIPNet,LocalAddr,sizeof(LocalAddr)) == -1)
{
RPT(RPT_ERR,"AddrIP str get fail");
return -1;
}
//IPv4 IPv6 均适用
HintAddr.ai_family = SOCK_AF_UNSPEC;
//任何addr/port均接受
HintAddr.ai_flags = AI_PASSIVE;
HintAddr.ai_socktype = SocketParam->sock_type;
HintAddr.ai_protocol = SocketParam->protocol;
RPT(RPT_WRN,"Local addr %d=%d %s/%s",SocketParam->AddrIP,LocalIPNet,LocalAddr,PortStr);
ret = getaddrinfo(LocalAddr,PortStr,&HintAddr,AddrList);
return ret;
}
/*****************************************************************************************
* 函数名称: sock_server_init
* 函数功能: 搜寻地址列表,查找可用套接字,tcp 套接字创建 绑定 监听
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_server_init(SOCK_OBJ *handle ,struct addrinfo *List)
{
int ret = -1;
int sock_fd = -1;
struct addrinfo *addr;
if(handle == NULL || List == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
//搜寻地址列表,查找可用套接字,tcp 套接字创建 绑定 监听
for (addr = List;addr != NULL;addr = addr->ai_next)
{
sock_fd = sock_create(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if(sock_fd < 0)
{
RPT(RPT_ERR, "socket create fail");
continue;
}
ret = sock_opt_list_set(handle,sock_fd);
if (ret < 0)
{
continue;
}
ret = sock_bind(sock_fd,addr);
if(ret < 0)
{
sock_close(sock_fd);
RPT(RPT_ERR, "bind fail");
continue;
}
RPT(RPT_WRN, "bind success");
if (addr->ai_socktype == SOCK_TCP_STREAM)
{
ret = sock_listen(sock_fd);
if(ret < 0)
{
sock_close(sock_fd);
RPT(RPT_ERR, "listen fail");
continue;
}
RPT(RPT_WRN, "listen success");
}
//此处显示仅IPv4有效
sock_print_addr(addr->ai_addr,"local addr ");
//bind listen successful
break;
}
//释放链表空间
freeaddrinfo(List);
if ( NULL == addr)
{
sock_fd = -1;
}
return sock_fd;
}
/*****************************************************************************************
* 函数名称: sock_Id_local_get
* 函数功能: 获取本地服务器的套接字描述符
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_Id_local_get(SOCK_OBJ *handle )
{
int sock_fd = 0;
int ret = 0;
if(handle == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
struct addrinfo *AddrList;
SOCK_PARAM *Params = NULL;
Params = &(handle->params);
ret = sock_addr_list_get(Params,&AddrList);
if (ret != 0)
{
RPT(RPT_ERR,"addrinfo list get fail");
return -1;
}
sock_fd = sock_server_init(handle,AddrList);
if (sock_fd < 0)
{
RPT(RPT_ERR,"sock server init fail");
ret = 0;
}
if (Params->protocol == SOCK_PROTO_TCP)
{
RPT(RPT_WRN,"tcp sock init success %d",sock_fd);
}
else if (Params->protocol == SOCK_PROTO_UDP)
{
RPT(RPT_WRN,"udp sock init success %d",sock_fd);
}
ret = sock_fd;
return ret;
}
/*****************************************************************************************
* 函数名称: sock_stream_recv_package
* 函数功能: 流套接字接收数据
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_stream_recv_package(SOCK_OBJ * SockObj,int sock_fd,int *ClntFd)
{
int ClntSockFd = 0;
int BuffSize = 0;
int RecvLen = 0;
int flags = 0;
void *pBuff = NULL;
SOCK_BUFF_OBJ *pSockBuff = NULL;
if(SockObj == NULL || ClntFd == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
ClntSockFd = sock_accept(sock_fd);
if (ClntSockFd < 0)
{
RPT(RPT_ERR,"local socket %d accept failed %d",sock_fd,ClntSockFd);
return -1;
}
RPT(RPT_WRN,"accept success %d",ClntSockFd);
if (SockObj->sock_recv_snd == SOCK_SEND_ONLY)
{
RPT(RPT_WRN,"sock send only");
return RecvLen;
}
*ClntFd = ClntSockFd;
pSockBuff= &(SockObj->sock_buff);
pBuff = pSockBuff->RecvBuff;
BuffSize = pSockBuff->RecvBuffLen;
flags = SockObj->params.RecvFlags;
memset((char*)pBuff,0,pSockBuff->RecvDataLen);
pSockBuff->RecvDataLen = 0;
RPT(RPT_WRN,"recv buffsize %d = %d",BuffSize,RecvLen);
while (RecvLen < BuffSize)
{
//描述符是否阻塞
if (sock_is_ready(ClntSockFd,3000) <= 0)
{
return -1;
}
RecvLen = sock_recv(ClntSockFd,pBuff,BuffSize,flags);
if(RecvLen < 0)
{
RPT(RPT_ERR, "recv data error");
return -1;
}
if (RecvLen == 0)
{
RPT(RPT_ERR, "recv data finished");
break;
}
RPT(RPT_WRN,"recv data %s",(char*)pBuff);
pSockBuff->RecvDataLen += RecvLen;
if(RecvLen < BuffSize)
{
pBuff += RecvLen;
BuffSize -= RecvLen;
RecvLen = 0;
}
}
RPT(RPT_WRN, "recv data success");
//sock_close(ClntSockFd);
return RecvLen;
}
extern void ctrl_frame_to_string(char *CFBuff);
/*****************************************************************************************
* 函数名称: sock_dgram_recv_package
* 函数功能: 数据包套接字接收数据
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_dgram_recv_package(SOCK_OBJ *SockObj,int sock_fd, int *ClntFd)
{
int BuffSize = 0;
int RecvLen = 0;
int flags = 0;
void *pBuff = NULL;
SOCK_BUFF_OBJ *pSockBuff = NULL;
struct sockaddr *ClntAddr;
socklen_t ClntAddrLen;
if(SockObj == NULL || ClntFd == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
if (SockObj->sock_recv_snd == SOCK_SEND_ONLY)
{
RPT(RPT_WRN,"sock send only");
return RecvLen;
}
ClntAddr = (struct sockaddr *)(&SockObj->clntAddr);
ClntAddrLen = SockObj->clntLen;
*ClntFd = sock_fd;
pSockBuff= &(SockObj->sock_buff);
pBuff = pSockBuff->RecvBuff;
BuffSize = pSockBuff->RecvBuffLen;
flags = SockObj->params.RecvFlags;
memset((char*)pBuff,0,pSockBuff->RecvDataLen);
pSockBuff->RecvDataLen = 0;
RecvLen = sock_recv_from_clntAddr(sock_fd, pBuff,BuffSize,flags,ClntAddr,&ClntAddrLen);
if(RecvLen < 0)
{
RPT(RPT_ERR, "udp recv error");
return -1;
}
RPT(RPT_WRN, "udp recv success %s",(char*)pBuff);
SockObj->clntLen = ClntAddrLen;
pSockBuff->RecvDataLen = RecvLen;
//客户机地址信息打印 适用于IPv4
sock_print_addr(ClntAddr,"client addr ");
/************************* 打印 接收消息 *****************************/
ctrl_frame_to_string(pBuff);
return RecvLen;
}
/*****************************************************************************************
* 函数名称: sock_server_recv
* 函数功能: 套接字接收数据
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_server_recv(sockets_handle h,int sock_fd,int *ClntFd)
{
SOCK_OBJ *handle = h;
int len = 0;
int type = handle->params.sock_type;
if(ClntFd == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
if (type == SOCK_TCP_STREAM)
{
len = sock_stream_recv_package(handle,sock_fd,ClntFd);
}
else if (type == SOCK_UDP_DGRAM)
{
len = sock_dgram_recv_package(handle,sock_fd,ClntFd);
}
return len;
}
/*****************************************************************************************
* 函数名称: sock_stream_send_package
* 函数功能: 流套接字发送数据
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_stream_send_package(int sock_fd,SOCK_OBJ * SockObj)
{
int DataSize = 0;
int SndLen = 0;
int flags = 0;
void *pBuff = NULL;
SOCK_BUFF_OBJ *pSockBuff = NULL;
if(SockObj == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
pSockBuff= &(SockObj->sock_buff);
pBuff = pSockBuff->SndBuff;
DataSize = pSockBuff->SndDataLen;
flags = SockObj->params.SndFlags;
SndLen = sock_send(sock_fd,pBuff,DataSize,flags);
if (SndLen < 0)
{
RPT(RPT_ERR,"tcp sock send failed");
return -1;
}
RPT(RPT_WRN, "tcp sock send success");
return SndLen;
}
/*****************************************************************************************
* 函数名称: sock_dgram_send_package
* 函数功能: 数据包套接字发送数据
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_dgram_send_package(int sock_fd,SOCK_OBJ * SockObj)
{
int DataSize = 0;
int SndLen = 0;
int flags = 0;
void *pBuff = NULL;
SOCK_BUFF_OBJ *pSockBuff = NULL;
struct sockaddr *ClntAddr;
socklen_t ClntAddrLen;
if(SockObj == NULL)
{
RPT(RPT_ERR,"NULL pointer!\n");
return -1;
}
ClntAddr = (struct sockaddr *)(&SockObj->clntAddr);
ClntAddrLen = SockObj->clntLen;
pSockBuff= &(SockObj->sock_buff);
pBuff = pSockBuff->SndBuff;
DataSize = pSockBuff->SndDataLen;
flags = SockObj->params.SndFlags;
RPT(RPT_WRN, "udp sock send data %s/%d",(char*)pBuff,DataSize);
//客户机地址信息打印 适用于IPv4
sock_print_addr(ClntAddr,"client addr ");
SndLen = sock_send_to_clntAddr(sock_fd, pBuff,DataSize,flags,ClntAddr,ClntAddrLen);
if(SndLen < 0)
{
RPT(RPT_ERR, "udp sock send error");
return -1;
}
RPT(RPT_WRN, "udp sock send success %d",SndLen);
return SndLen;
}
/*****************************************************************************************
* 函数名称: sock_server_send
* 函数功能: 发送数据
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static int sock_server_send(sockets_handle h,int sock_fd)
{
SOCK_OBJ *handle = h;
int len = 0;
int type = handle->params.sock_type;
if (type == SOCK_TCP_STREAM)
{
len = sock_stream_send_package(sock_fd,handle);
}
else if (type == SOCK_UDP_DGRAM)
{
len = sock_dgram_send_package(sock_fd,handle);
}
return len;
}
/*****************************************************************************************
* 函数名称: sock_server_pthread
* 函数功能: 套接字线程
* 输入参数:
* 输出参数:
* 返回结果:
* 修改记录:
******************************************************************************************/
static void sock_server_pthread(sockets_handle h)
{
int sock_fd = 0;
int ClntSockFd = 0;
int RecvLen = 0;