8c2952457
김태훈
응용 프로그램 추가
|
1
2
3
|
/**
@file udp.c
@date 2009-03-19
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
4
5
|
@author 오재경 freefrug@falinux.com
@brief udp 를 사용한 통신을 담당한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
6
7
|
@modify
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
8
|
2010-08-18 (장길석) mingw와 함께 사용할 수 있는 코드 추가
|
8c2952457
김태훈
응용 프로그램 추가
|
9
10
11
12
13
14
15
|
@todo
@bug
@remark
@warning
*/
//
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
16
17
|
// 저작권 에프에이리눅스(주)
// 외부공개 금지
|
8c2952457
김태훈
응용 프로그램 추가
|
18
19
|
//
//----------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
20
|
#define EMBEDDED_LINUX // 이렇게 처리하지 않으면 EClipse에서 C 영역이 회색 바탕이 됨
|
8c2952457
김태훈
응용 프로그램 추가
|
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
|
#ifdef MS_WIN32
#undef EMBEDDED_LINUX
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#ifdef EMBEDDED_LINUX
#include <sys/un.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#else
#include <windows.h>
#include <winsock2.h>
#endif
#include <pollmng.h>
#include <udp.h>
char desc_udp[] = "falinux udp ver 0.2.0";
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
56
|
/// udp 개별 구조체
|
8c2952457
김태훈
응용 프로그램 추가
|
57
58
59
60
61
62
63
|
typedef struct {
int port;
int im_server;
struct sockaddr_in addr;
} udp_priv_t;
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
64
|
static poll_obj_t *tmp_udp_poll = NULL; // poll 관리객체없이 전송함수를 위해
|
8c2952457
김태훈
응용 프로그램 추가
|
65
66
67
|
//------------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
68
69
70
|
/** @brief udp 소켓을 서버형태로 open 한다.
@param port 포트번호
@return poll_obj_t 형태의 포인터
|
8c2952457
김태훈
응용 프로그램 추가
|
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
*///----------------------------------------------------------------------------
#ifdef EMBEDDED_LINUX
poll_obj_t *udp_open_server( int port )
{
struct sockaddr_in addr_svr;
poll_obj_t *obj;
udp_priv_t *udp;
int option;
int sockfd;
sockfd = socket( PF_INET, SOCK_DGRAM, 0 );
if ( sockfd < 0 )
{
perror( "udp open error:" );
return NULL;
}
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
90
91
|
// TIME-WAIT 상태에 있는 소켓에 할당되어 있는 IP 주소와 포트를 바로 사용할 수 있도록
// SO_REUSEADDR 의 옵션 값을 TRUE 로
|
8c2952457
김태훈
응용 프로그램 추가
|
92
93
94
|
option = 1;
setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
95
|
// 소켓을 시스템에 연결한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
96
97
98
99
100
101
102
103
104
105
106
107
|
bzero( &addr_svr, sizeof(struct sockaddr_in) );
addr_svr.sin_family = AF_INET;
addr_svr.sin_addr.s_addr = htonl( INADDR_ANY );
addr_svr.sin_port = htons( port );
if( bind( sockfd, (struct sockaddr *)&addr_svr, sizeof(struct sockaddr_in) ) < 0 )
{
perror("udp bind error :");
close( sockfd );
return NULL;
}
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
108
|
// udp 만의 정보를 설정한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
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
|
udp = (udp_priv_t *)malloc( sizeof(udp_priv_t) );
udp->im_server = 1;
udp->port = port;
obj = poll_add( sockfd );
obj->type = STYP_UDP;
obj->priv = (void *)udp;
tmp_udp_poll = obj;
return obj;
}
#else
poll_obj_t *udp_open_server( int port )
{
SOCKET hSock;
SOCKADDR_IN sckAddr;
poll_obj_t *obj;
udp_priv_t *udp;
char option;
hSock = socket( PF_INET, SOCK_DGRAM, 0 );
if ( INVALID_SOCKET == hSock){
perror( "udp open error:");
return NULL;
}
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
139
140
|
// TIME-WAIT 상태에 있는 소켓에 할당되어 있는 IP 주소와 포트를 바로 사용할 수 있도록
// SO_REUSEADDR 의 옵션 값을 TRUE 로
|
8c2952457
김태훈
응용 프로그램 추가
|
141
142
143
|
option = 1;
setsockopt( hSock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
144
|
// 소켓을 시스템에 연결한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
145
146
147
148
149
150
151
152
153
154
155
156
|
memset( &sckAddr, 0, sizeof( sckAddr));
sckAddr.sin_family = AF_INET;
sckAddr.sin_addr.s_addr = htonl( INADDR_ANY );
sckAddr.sin_port = htons( port );
if( SOCKET_ERROR == bind( hSock, ( SOCKADDR *)&sckAddr, sizeof( sckAddr) ))
{
perror("udp bind error");
closesocket( hSock );
return NULL;
}
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
157
|
// udp 만의 정보를 설정한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
udp = (udp_priv_t *)malloc( sizeof(udp_priv_t) );
udp->im_server = 1;
udp->port = port;
fd_t pSock = malloc( sizeof( SOCKET));
*( SOCKET*)pSock = hSock;
obj = poll_add( pSock);
obj->type = STYP_UDP;
obj->priv = (void *)udp;
tmp_udp_poll = obj;
return obj;
}
#endif
//------------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
177
178
|
/** @brief udp 소켓을 클라이언트 형태로 open 한다.
@return poll_obj_t 형태의 포인터
|
8c2952457
김태훈
응용 프로그램 추가
|
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
*///----------------------------------------------------------------------------
#ifdef EMBEDDED_LINUX
poll_obj_t *udp_open_client( void )
{
poll_obj_t *obj;
udp_priv_t *udp;
int sockfd;
sockfd = socket( PF_INET, SOCK_DGRAM, 0 );
if ( sockfd < 0 )
{
perror( "udp open error:" );
return NULL;
}
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
196
|
// udp 만의 정보를 설정한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
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
|
udp = (udp_priv_t *)malloc( sizeof(udp_priv_t) );
udp->im_server = 0;
udp->port = -1;
obj = poll_add( sockfd );
obj->type = STYP_UDP;
obj->priv = (void *)udp;
tmp_udp_poll = obj;
return obj;
}
#else
poll_obj_t *udp_open_client( void )
{
SOCKET hSock;
poll_obj_t *obj;
udp_priv_t *udp;
hSock = socket( PF_INET, SOCK_DGRAM, 0 );
if ( INVALID_SOCKET == hSock){
perror( "udp open error:");
return NULL;
}
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
225
|
// udp 만의 정보를 설정한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
udp = (udp_priv_t *)malloc( sizeof(udp_priv_t) );
udp->im_server = FALSE;
udp->port = -1;
fd_t pSock = malloc( sizeof( SOCKET));
*( SOCKET*)pSock = hSock;
obj = poll_add( pSock);
obj->type = STYP_UDP;
obj->priv = (void *)udp;
tmp_udp_poll = obj;
return obj;
}
#endif
//------------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
244
245
|
/** @brief udp 소켓을 close 한다.
@param obj 폴객체 포인터
|
8c2952457
김태훈
응용 프로그램 추가
|
246
247
248
249
250
251
252
253
254
255
|
*///----------------------------------------------------------------------------
void udp_close( poll_obj_t *obj )
{
#ifdef EMBEDDED_LINUX
close( obj->fd );
#else
closesocket( *( ( SOCKET *)obj->fd));
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
256
|
free( obj->fd); // SOCKET * 를 해제한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
257
258
259
260
261
262
263
264
265
266
267
268
269
|
#endif
if ( obj->priv )
{
free( obj->priv );
}
poll_delete( obj );
if ( tmp_udp_poll == obj ) tmp_udp_poll = NULL;
}
//------------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
270
271
272
|
/** @brief udp 폴객체를 포트번호로 찾는다.
@param port 포트번호
@return obj 폴객체 포인터
|
8c2952457
김태훈
응용 프로그램 추가
|
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
|
*///----------------------------------------------------------------------------
poll_obj_t *udp_get_byport( int port )
{
poll_obj_t *obj;
udp_priv_t *udp;
int idx, count;
count = poll_count();
for(idx=0; idx<count; idx++)
{
obj = poll_get_obj( idx );
udp = (udp_priv_t *)obj->priv;
if ( udp )
{
if ( udp->port == port )
{
return obj;
}
}
}
return NULL;
}
//------------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
298
299
300
301
|
/** @brief 자료를 송신한 클라이언트로 데에터를 재 전송한다
@param obj 폴객체 포인터
@param len 버퍼의 길이
@return 전송된 데이타 개수
|
8c2952457
김태훈
응용 프로그램 추가
|
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
|
*///----------------------------------------------------------------------------
int udp_echo( poll_obj_t *obj, char *buf, int len )
{
struct sockaddr_in *paddr;
udp_priv_t *udp;
int wrcnt;
udp = (udp_priv_t *)(obj->priv);
paddr = &(udp->addr);
#ifdef EMBEDDED_LINUX
wrcnt = sendto( obj->fd, buf, len, 0, (struct sockaddr *)paddr, sizeof( struct sockaddr_in) );
#else
SOCKET hSock = *( SOCKET *)obj->fd;
wrcnt = sendto( hSock, buf, len, 0, (struct sockaddr *)paddr, sizeof( struct sockaddr_in) );
#endif
if ( 0 > wrcnt )
{
perror( "udp send error:" );
}
return wrcnt;
}
//------------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
331
332
333
334
335
336
337
|
/** @brief udp 소켓을 통해 데이타를 전송한다.
@param obj 폴객체 포인터
@param host 상대방 IP 나 호스트이름 문자열포인터
@param port 상대방 포트번호
@param buf 전송버퍼
@param len 버퍼의 길이
@return 전송한 데이타 개수
|
8c2952457
김태훈
응용 프로그램 추가
|
338
339
340
341
342
343
|
*///----------------------------------------------------------------------------
int udp_write( poll_obj_t *obj, char *host, int port, char *buf, int len )
{
struct sockaddr_in udp_addr;
int wrcnt;
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
344
|
// 상대편 주소를 설정한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
345
346
347
348
349
|
memset( &udp_addr, 0, sizeof( struct sockaddr_in) );
udp_addr.sin_family = AF_INET;
udp_addr.sin_addr.s_addr = inet_addr( host );
udp_addr.sin_port = htons( port );
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
350
|
// 전송한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
|
#ifdef EMBEDDED_LINUX
wrcnt = sendto( obj->fd, buf, len, 0, (struct sockaddr *)&udp_addr, sizeof(udp_addr) );
#else
SOCKET hSock = *( SOCKET *)obj->fd;
wrcnt = sendto( hSock, buf, len, 0, (struct sockaddr *)&udp_addr, sizeof(udp_addr) );
#endif
if ( 0 > wrcnt )
{
perror( "udp send error:" );
}
return wrcnt;
}
//------------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
371
372
373
374
|
/** @brief udp 소켓을 통해 데이타를 읽는다.
@param obj 폴객체 포인터
@param len 버퍼의 길이
@return 전송된 데이타 개수
|
8c2952457
김태훈
응용 프로그램 추가
|
375
376
377
378
379
380
381
382
383
384
385
|
*///----------------------------------------------------------------------------
int udp_read( poll_obj_t *obj, char *buf, int len )
{
struct sockaddr_in *paddr;
udp_priv_t *udp;
int addr_len;
int rdcnt;
udp = (udp_priv_t *)(obj->priv);
paddr = &(udp->addr);
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
386
|
// 데이타를 읽는다.
|
8c2952457
김태훈
응용 프로그램 추가
|
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
|
addr_len = sizeof( struct sockaddr_in);
#ifdef EMBEDDED_LINUX
rdcnt = recvfrom( obj->fd, buf, len, 0, (struct sockaddr *)paddr, (socklen_t *)&addr_len );
#else
SOCKET hSock = *( SOCKET *)obj->fd;
rdcnt = recvfrom( hSock, buf, len, 0, ( SOCKADDR *)paddr, &addr_len);
#endif
if ( 0 > rdcnt )
{
perror( "udp recv error:" );
}
//printf( "host=%s port=%d
", inet_ntoa( udp->addr.sin_addr ), udp->addr.sin_port );
return rdcnt;
}
//------------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
410
411
412
413
414
|
/** @brief udp 소켓으로 마지막으로 수신한 호스트를 찾는다.
@param obj 폴객체 포인터
@param host 상대편 호스트를 돌려줄 문자열 포인터
@param port 상대편 호스트가 사용한 포트번호를 돌려줄 정수형 포인터
@return 의미없음
|
8c2952457
김태훈
응용 프로그램 추가
|
415
416
417
418
419
420
421
422
423
424
425
426
427
|
*///----------------------------------------------------------------------------
int udp_get_remote_host( poll_obj_t *obj, char *host, int *port )
{
udp_priv_t *udp;
udp = (udp_priv_t *)(obj->priv);
strcpy( host, inet_ntoa( udp->addr.sin_addr ) );
*port = udp->addr.sin_port;
return 0;
}
//------------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
428
429
430
431
432
433
434
|
/** @brief poll 객체없이 udp 소켓을 통해 데이타를 전송한다.
@param host 상대방 IP 나 호스트이름 문자열포인터
@param port 상대방 포트번호
@param buf 전송버퍼
@param len 버퍼의 길이
@return 전송한 데이타 개수
@remark udp_open_server(), udp_open_client() 함수는 한번 호출되어야 한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
435
436
437
438
439
440
441
442
443
444
445
|
*///----------------------------------------------------------------------------
int udp_write_simple( char *host, int port, char *buf, int len )
{
if ( tmp_udp_poll )
{
return udp_write( tmp_udp_poll, host, port, buf, len );
}
return -1;
}
//------------------------------------------------------------------------------
|
3061c73f6
김태훈
인코딩 변경 EUC-KR -> ...
|
446
447
448
449
450
|
/** @brief poll 객체없이 udp 소켓을 통해 데이타를 읽는다.
@param buf 전송버퍼
@param len 버퍼의 길이
@return 전송된 데이타 개수
@remark udp_open_server(), udp_open_client() 함수는 한번 호출되어야 한다.
|
8c2952457
김태훈
응용 프로그램 추가
|
451
452
453
454
455
456
457
458
459
460
461
462
|
*///----------------------------------------------------------------------------
int udp_read_simple( char *buf, int len )
{
if ( tmp_udp_poll )
{
return udp_read( tmp_udp_poll, buf, len );
}
return -1;
}
|