Title Unassigned.

Similar documents
untitled

VoIP Make a Rtp Call VoIP Abstract... 2 VoIP RTP...3 Socket IP...9 Config Two Voice-hub

ebook35-21

嵌入式Linux块设备驱动开发解析

/ / (FC 3)...

CC213

Slide 1

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1

新・明解C言語入門編『索引』

_汪_文前新ok[3.1].doc

Chap6.ppt

Chapter #

Chapter 5- 运输层 (5)-2017

untitled

ebook12-1

FY.DOC

新版 明解C++入門編

Microsoft PowerPoint - Socket programming.ppt [相容模式]

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

(Methods) Client Server Microsoft Winsock Control VB 1 VB Microsoft Winsock Control 6.0 Microsoft Winsock Control 6.0 1(a). 2

下表所示, 此时 protocol 参数可使用缺省值 0 ; 但如果还有多个协议供选择, 则必须使用 protocol 参数来标识 协议族 ( 仅考虑 IP 协议 传送类型 protocol 参数常量 协议类型 族 ) (/usr/include/linux/in.h) SOCK_STREAM IP

PowerPoint Presentation

Chap04

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;

C 1

Linux網路傳輸設定

/3/15 1, linux. linux,,. : 1.NAT ; 2. (load balance, virtual server);; 3. ; 4. ; 5. 6.VPN; 7. ; 8. ; 9.. (,

untitled

C语言的应用.PDF

《C语言程序设计》教材习题参考答案

UDP 8.2 TCP/IP OSI OSI 3 OSI TCP/IP IP TCP/IP TCP/IP Transport Control Protocol TCP User Datagram Protocol UDP TCP TCP/IP IP TCP TCP/IP TC

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.07.doc

Slide 1


C/C++语言 - C/C++数据

第11章 可调内核参数

Linux网络编程socket错误分析

2013 C 1 # include <stdio.h> 2 int main ( void ) 3 { 4 int cases, a, b, i; 5 scanf ("%d", & cases ); 6 for (i = 0;i < cases ;i ++) 7 { 8 scanf ("%d %d

untitled

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File

The Library SysLibSockets

( CIP) /. :, ( ) ISBN TP CIP ( 2005) : : : : * : : 174 ( A ) : : ( 023) : ( 023)

IP505SM_manual_cn.doc

提纲 1 2 OS Examples for 3

ebook15-C

JLX

51 C 51 isp 10 C PCB C C C C KEIL

工程硕士信息通信网实验讲义.doc

bingdian001.com

概述

Bus Hound 5

华清远见就业优势倍增项目手册

Ps22Pdf

untitled

提问袁小兵:

<4D F736F F F696E74202D20A1B6CFEEC4BFD2BB20B3F5CAB6BCC6CBE3BBFACDF8C2E7A1B7C8CECEF1C8FD20CAECCFA A1A24950D0ADD2E9BACD4950B5D8D6B72E707074>

ebook15-10

C6_ppt.PDF

chap07.key


Guava学习之Resources

AL-M200 Series

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un

第7章-并行计算.ppt

《C语言程序设计》第2版教材习题参考答案

Microsoft Word - MAN2023A_CH_APPONE.doc

威 福 髮 藝 店 桃 園 市 蘆 竹 區 中 山 里 福 祿 一 街 48 號 地 下 一 樓 50,000 獨 資 李 依 純 105/04/06 府 經 登 字 第 號 宏 品 餐 飲 桃 園 市 桃 園 區 信 光 里 民

Microsoft Word - 11.doc

Microsoft Word - 01.DOC

untitled

C/C++语言 - 分支结构

ebook

c_cpp

通过Hive将数据写入到ElasticSearch

C/C++ 语言 - 循环

ebook15-12

C 1 # include <stdio.h> 2 int main ( void ) { 4 int cases, i; 5 long long a, b; 6 scanf ("%d", & cases ); 7 for (i = 0;i < cases ;i ++) 8 { 9

NOWOER.OM m/n m/=n m/n m%=n m%n m%=n m%n m/=n 4. enum string x1, x2, x3=10, x4, x5, x; 函数外部问 x 等于什么? 随机值 5. unsigned char *p1; unsigned long *p

穨control.PDF

概述

Microsoft PowerPoint - os_4.ppt

ebook122-3

C PICC C++ C++ C C #include<pic.h> C static volatile unsigned char 0x01; static volatile unsigned char 0x02; static volatile unsigned cha

Microsoft Word - MSP430 Launchpad 指导书.docx

<4D F736F F D20C9CFBAA3CAD0BCC6CBE3BBFAB5C8BCB6BFBCCAD4C8FDBCB6BFBCCAD4B4F3B8D95FBDA8D2E9B8E55F5F E646F63>

Microsoft Word - AN3259C

MASQUERADE # iptables -t nat -A POSTROUTING -s / o eth0 -j # sysctl net.ipv4.ip_forward=1 # iptables -P FORWARD DROP #

华恒家庭网关方案

untitled

1

全国计算机技术与软件专业技术资格(水平)考试

Intruduction to the NGINX stream subsystem and OpenResty's support

ebook71-13

目录 1. RK 支持的编解码类型 头文件与库文件 结构体介绍 编解码枚举定义 编解码结构体定义 解码调用流程 解码创建过程 解码过程 解码销毁过程

AN INTRODUCTION TO PHYSICAL COMPUTING USING ARDUINO, GRASSHOPPER, AND FIREFLY (CHINESE EDITION ) INTERACTIVE PROTOTYPING

<4D F736F F D204C696E7578CFB5CDB3B5F7D3C3C1D0B1ED>

6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C C C51 C51 ANSI C MCS-51 C51 ANSI C C C51 bit Byte bit sbit

untitled

Transcription:

基本操作流程 用 usock 函数编写 TCP 客户端程序 usock_open 用 usock_open 获取一个 usock 描述符 usock_connect 用刚才返回的描述符进行 connect 操作 connect 时指定的对方地址用 usockaddr_in 结构体描述 usock_write 用 usock_write 写数据给对方, 用 usock_read 读取对方发来的数据 usock_read usock_close 完成该连接上的所有数据传输后, 用 usock_close 关闭 usock 描述符, 关闭后, 此描述符不应再被使用 usock 函数与 BSD socket 函数的对比 BSD Socket usock 函数描述 socket usock_open usock usock_open(long af, short type, short protocol); 只支持一种 af, 即 AF_INET 只支持一种 type, 即 US_STREAM 注意不要写成 SOCK_STREAM protocol 参数添成 0 返回值 : 成功返回一个大于或等于 0 的 usock 描述符 失败返回负值, 失败的原因一般是描述符用尽 usock 可以支持同时打开 12 个描述符 close usock_close int usock_close(usock s); 一般不会失败, 除非传给了错误的 s 参数 sockaddr_in 结构体 usockaddr_in 结构体 usockaddr_in 结构体用于描述台主机的 IP 地址, 存储于其中 IP 地址与端口号是以网络字节序表示的 BSD socket 中凡是用到 sockaddr_in 的地方到了 usock 上都要改用

usockaddr_in struct usockaddr_in unsigned char sin_len; unsigned char sin_family; unsigned short sin_port; struct uin_addr sin_addr; char sin_zero[8]; ; struct uin_addr unsigned long s_addr; ; bind usock_bind int usock_bind(usock s, struct usockaddr_in * addr); 在发起连接 (usock_connect) 前调用此函数, 用于指定本端所用的 IP 地址与端口号 usockaddr_in 的 sin_addr 成员可以指定为 0, 或本机实际的 IP 地址, 这样 usock 将使用本机的实际 IP 地址, 其他的值将导致后续的 usock_connect 失败 返回值 : 一般不会失败, 即返回 0 connect usock_connect int usock_connect(usock s, const struct usockaddr_in * addr, unsigned char tos, unsigned int timeout); tos 参数, 无用处, 应指定为 0 timeout 参数 : 指定 connect 操作的超时值, 以毫秒为单位, 必须用大于 0 的数值 在此时间内成功建立连接则返回 0; 未成功建立连接则返回负值错误码, 一般为 TCPERR_TIMEOUT send write writev recv read readv usock_write usock_read int usock_write(usock s, void *buf, unsigned int len, unsigned int timeout); 将 buf 指向的 len 字节数据写入 socket, 超时值用 timeout 指示 ( 以毫秒为单位, 必须大于 0) 大于等于 0 的返回值指示写入了多少字节 负返回值指示错误码 int usock_read(usock s, void *buf, unsigned int len, unsigned int timeout); usock_read 试图从 socket 中读出 len, 存入 buf 指向的缓冲区中, 超时值由 timeout 指定 ( 以毫秒为单位, 必须大于 0) 若提供的参数合法,usock_read 将在以下三种情况下返回 1. 读到 len 字节 2. 收到对方 TCP 发来的 FIN 或 RST 3. 超时 此情况下 usock_read 的返回值可能在 0~ len 之间

特别注意 : 只收到一个对方的 TCP 报文并不会使 usock_read 返回, 这是不同于 BSD socket 的地方 usock_read 的这个特点在使用上可能会带来不便 返回值 : 返回 0 或正值表示读到的字节数 返回 TCPERR_EOF 表示收到了对方的 FIN 返回 TCPERR_RESET 表示收到了对方的 RST 返回其他的负值表示一种错误 select getsockname getpeername setsockopt getsockopt ntohs, ntohl htons, htonl 无 无 NetGetHostIPAddr usock_set_opt usock_get_opt ntohs, ntohl htons, htonl int NetGetHostIPAddr(unsigned long *phostip, char szhostip[16]); 仅仅用于获取本机的 IP 地址 phostip 与 szhostip 都是可选参数, phostip 用于获取主机字节序的本机 IP 地址 ;szhostip 则会被存入转换为字符串的 IP 地址 ( 如 192.168.0.2 ) 在 850 未拨号的情况下, 填入的是 0 地址, 同时返回 -1 usock 底下的协议栈没有 127.0.0.1 的概念 拨号成功的情况下,pHostIP 与 szhostip 中被填入 PPP server 分配给自己的 IP 地址 int usock_set_opt(usock sock, int optname, const void *optval, int optlen); int usock_get_opt(usock sock, int optname, void *optval, int optlen); usock 的这两个函数没有 level 参数 usock 仅支持一个 socket 选项 ( 指定于 optname 参数 ): USOCKOPT_RST_ON_CLOSE 当用 usock_set_opt 设置此选项时,optval 参数本身若为非 NULL 指针, 表示在 usock_close 时将向对方发 RST, 若 optval 为 NULL, 则向对方发 FIN usock_close 时发 FIN 是默认行为 用 usock_get_opt 获取此选项时, optval 应指向调用者提供的一个 int 变量, 该变量返回 1 指示 RST 行为,0 指示 FIN 行为 usock 中这几个函数的名称及作用与 BSD socket 的相同 inet_addr inet_ntoa uinet_addr uinet_ntoa uinet_addr 的作用及函数参数与 BSD socket 的相应函数相同 uinet_ntoa 略有不同 : char * uinet_ntoa(unsigned long ip_addr_network_order, char buf[]); uinet_ntoa 将转换出的 IP 地址字符串填于用户的 buf 缓冲区中, buf 缓冲区应该至少为 16 字节 uinet_addr 的返回值即是 buf 的值

更多细节说明 usock 错误码 usock 函数底下使用的是 ucip,ucip 定义的如下负值错误码也是 usock 函数可能返回的错误码 这些错误码的部分在刚才的 usock_connect usock_read 中解释过 #define TCPERR_EOF -1 /* End of data. */ #define TCPERR_ALLOC -2 /* Unable to allocate a control block. */ #define TCPERR_PARAM -3 /* Invalid parameters. */ #define TCPERR_INVADDR -4 /* Invalid address. */ #define TCPERR_CONFIG -5 /* Invalid configuration. */ #define TCPERR_CONNECT -6 /* No connection. */ #define TCPERR_RESET -7 /* Connection reset received. */ #define TCPERR_TIMEOUT -8 /* Timeout on transmission. */ usock 不支持的东西 不支持 UDP 插口 不支持 listen accept 操作 其他 usock_open 只在 850 返回成功后才能返回有效的 usock 描述符, 这意味着你没有办法建立一个自己到自己的连接来测试 usock 的工作 当然,usock 不支持 listen accept 操作也使得你无法做到这一点 具体的例子 下面的例子演示了如何使用 usock 函数 该例子程序连接一个 IP 地址硬编码于程序中的服务器, 写入一个简单的 HTTP 请求字符串, 然后循环地读取服务器响应, 直到读取结束或超过自定义的超时时间为止 该程序还展示了以下特性 连接服务器并读取服务器数据的代码是由独立的工作线程 ( 任务 ) 完成的, 因此主线程可以应终端用户的要求对工作线程进行 打断 虽然程序安排的 usock_connect 超时时间是 12 秒, 但是用 usock_connect 连接服务器的过程却放在一个循环中进行, 循环中的每次 usock_connect 调用指定一个较短的超时值 (3 秒 ), 这样,connect 循环每 3 秒就能够返回并检查以下主线程是否设置了退出标志 usock_read 循环采用了个 usock_connect 循环类似的方法来周期性地检测退出标志 此例子要写给服务器的数据很短 ( 十几字节 ), 所以就没有为 usock_write 安排循环, 但如果要用 usock_write 写入大量数据, 则也可以用同样的循环方法, 以便接受用户的 打断 必须用循环的原因在于 : 没有办法中断一个已经在进行中的 usock_read 或 usock_write 调用 该例子由两个 cpp 文件构成,main.cpp 是演示 usock 函数的主文件,my_create_task.cpp 是对 UDeleteTask 的一个简单封装, 使得创建任务的代码会显得少些

//////////////////////// main.cpp ////////////////////// #include <ubase.h> #include <net/unet.h> #include "ubcommop.h" struct SThreadParam usockaddr_in addrpeer; int quit_flag; int end_flag; ; void go_connection(usock sock, SThreadParam *ptp) const usockaddr_in *p_addrpeer = &ptp->addrpeer; int re; time_t sec_limit = 0; printf("connecting...\n"); sec_limit = time(null)+12; // total timeout 12 seconds for(;;) if(ptp->quit_flag) printf("canceled.\n"); return; re = usock_connect(sock, p_addrpeer, 0, 3000); if(re==0) // connected break; else if(re==tcperr_timeout) if(time(null)>sec_limit) printf("connect timeout.\n"); return; // thoroughly timeout else // other error printf("connect error(%d).\n", re); return; const char *szwr = "GET / HTTP/1.1\nHost:\n\n"; int wrlen = strlen(szwr); usock_write(sock, szwr, wrlen, 1000); // 严格起见, 应该把 usock_write 写于循环中, 若 usock_write 的返回值小于 wrlen, // 还可以再次调用 usock_write 写入剩余部分

printf("reading...\n"); time_t sec_last_read = time(null); // 记录上一次读到数据的时间 int nrd = 0, totrd = 0; char rbuf[2048]; // 注意, 堆栈上的数组不要开太大 for(;;) if(ptp->quit_flag) printf("canceled.\n"); return; nrd = usock_read(sock, rbuf, sizeof(rbuf), 3000); if(nrd>0) totrd += nrd; // To-do: Copy data read(`nrd' bytes) to your own buffer... sec_last_read = time(null); else if(nrd==0) if(time(null)-sec_last_read > 12) // 如果持续 12 秒没有读到数据, 则退出 printf("read timeout.\n"); break; else // nrd<0 printf("end usock_read(%d).\n", nrd); break; printf("total read %d bytes.\n", totrd); void test_usock(sthreadparam *ptp) usock sock = usock_open(af_inet, US_STREAM, 0); if(sock<0) printf("usock_open() fail!"); return; go_connection(sock, ptp); if(ptp->quit_flag) usock_set_opt(sock, USOCKOPT_RST_ON_CLOSE, (void*)1, sizeof(int)); // This causes usock_close() to send RST instead of FIN.

usock_close(sock); printf("usock-done."); void _thread_test_usock(void *param) SThreadParam *ptp = (SThreadParam*)param; test_usock(ptp); ptp->end_flag = 1; // tell the main thread that we re done, // and can be safely killed. while(1) USleep(1000); // wait to be killed int main(void) clsrc(); SThreadParam tp = 0; tp.quit_flag = 0; tp.end_flag = 0; tp.addrpeer.sin_len = sizeof(usockaddr_in); tp.addrpeer.sin_family = AF_INET; tp.addrpeer.sin_addr.s_addr = uinet_addr("192.168.0.1"); tp.addrpeer.sin_port = htons(80); char szerr[40]; HANDLE htask = ubasecreatetask(_thread_test_usock, &tp, SYS_PRIO_USER, 16000, NULL, szerr, sizeof(szerr)); // create working thread if(htask==null) printf(szerr); USleep(1000); return 1; // If a key is press, break the working thread. if(kbdgetkey(timeout_infinite)) tp.quit_flag = 1; while(!tp.end_flag) USleep(500); UDeleteTask(hTask); printf("<end>"); KbdGetKey(TIMEOUT_INFINITE); return 0; //////////////////////// my_create_task.h ////////////////////// #ifndef my_create_task_h #define my_create_task_h

#ifdef cplusplus extern"c" #endif HANDLE ubasecreatetask(void (*pfunc)(void*), void *ptaskparam, int TaskPrio, int StackSize, const char sztaskname[k_name_length], char *errbuf, int bufsz); #ifdef cplusplus //extern"c" #endif #endif //////////////////// my_create_task.cpp ////////////////// #include <ubase.h> #include <mm_snprintf.h> #include "my_create_task.h" HANDLE ubasecreatetask(void (*pfunc)(void*), void *ptaskparam, int TaskPrio, int StackSize, const char sztaskname[k_name_length], char *errbuf, int bufsz) ST_TASKCREATE stc = 0; stc.pfunc = pfunc; stc.pparam = ptaskparam; stc.nprio = TaskPrio; stc.nstacksize = StackSize; int i; if(sztaskname) for(i=0; i<k_name_length-1; i++) stc.pname[i] = sztaskname[i]; if(sztaskname[i]=='\0') break; stc.pname[k_name_length-1] = '\0'; HANDLE htask = UCreateTask(&stc); if(htask==null && errbuf) mm_snprintf(errbuf, bufsz, "UCreateTask()fail,err=%d.", stc.nerrcode); return NULL; return htask;

History: [2004-11-10] 初稿 要求用 utools2.03.009 来编译链接例子程序 若使用 utools2.03.008 则 usock_set_opt, usock_get_opt 函数无法使用