C语言实的串行通信接口程序(2)
作者:佚名; 更新时间:2014-12-05
nt",
ws-overlappedwindow,cw-usedefault,cw-usedefault,
cw-usedefault,cw-usedefault,
null,null,hinstance,null);
if (!hwnd)
return (false);
showwindow(hwnd,ncmdshow);
updatewindow(hwnd);
/*给主窗口函数发送wm-user消息*/
postmessage(hwnd,wm-user,(wparam) 0,(lparam) 0);
while (getmessage(&msg,null,null,null)) {
translatemessage(&msg);
dispatchmessage(&msg);
}
return (msg.wparam);
}
主窗口函数clientproc是程序的主要部分,它处理相关的消息:在接到消息wm-user后,它调用函数wsastartup()初始化windows sockets dll,并检查其版本号,然后通过主机名获取主机地址;在接到消息wm-command时,如果是命令idm-start,则调用子程序client()建立套接字,并试图和服务器建立连接,如果是命令idm-stop,则调用函数wsacleanup()终止windows sockets dll,并发出终止应用程序的消息;在接到消息um-sock时,它根据参数lparam指示的网络事件,进行相应的操作,然后选择下一个期望的网络事件。


程序3:部分windows程序源代码(主窗口函数)
long far pascal
clientproc(hwnd hwnd, unsigned message, uint wparam, long lparam)
{
int length,i;
wsadatawsadata;/*描述windows sockets实现细节的数据结构*/
intstatus;
switch (message) {
case wm-user:
status=wsastartup(0x101,&wsadata);
if (status !=0) {
alertuser(hwnd,"wsastartup() failed");
postquitmessage(0);
}
if (lobyte(wsadata.wversion) !=1 || hibyte(wsadata.wversion) !=1)
{ /*现在支持的版本是winsock.dll 1.1*/
alertuser(hwnd, "wsastartup() version not match");
wsacleanup();
postquitmessage(0);
}
hostaddr=gethostbyname(server-address);
if (hostaddr==null) {
alertuser(hwnd, "gethostbyname error ");
wsacleanup ();
postquitmessage(0);
}
memcpy(&hostnm,hostaddr,sizeof(struct hostent));
break;
case wm-command:
switch (wparam) {
case idm-start:
if (!client(hwnd)) {
closesocket(s);
alertuser(hwnd, "start failed");
}
break;
case idm-stop:
wsacleanup();
postquitmessage(0);
break;
}
break;
case um-sock:
switch (lparam) {
case fd-connect:/*网络事件:连接建立*/
if (!set-select(hwnd, fd-write))/*选择:期望发送*/
closesocket(s);
break;
case fd-read:/*网络事件:读准备好*/
if (!receive-pkt(hwnd)) {/*接收数据*/
alertuser(hwnd, "receive packet failed");
closesocket(s);
break;
}
if (!set-select(hwnd, fd-write))/*选择:期望发送*/
closesocket(s);
break;
case fd-write:/*网络事件:写准备好*/
for (i=0;i<1024;i++)
buffer=(char) 'a'+i % 26;
length=1024;
if (!(send-pkt(hwnd,length))) {/*发送数据*/
alertuser(hwnd, "packet send failed");
closesocket(s);
break;
}
if (!set-select(hwnd, fd-read)) /*选择:期望接收*/
closesocket(s);
break;
case fd-close:/*网络事件:连接关闭。操作:停止异步选择*/
if (wsaasyncselect(s,hwnd,0,0)==socket-error)
alertuser(hwnd, "wsaasyncselect failed");
alertuser(hwnd, "socket has been closed");
break;
default:/*网络出错则警告,其他事件忽略*/
if (wsagetselecterror(1param) !=0) {
alertuser(hwnd, "socket report failure");
closesocket(s);
break;
}
break;
}
break;
case wm-destroy:
closesocket(s);/*关闭窗口前应该关闭套接字,并*/
wsacleanup();/*终止windows sockets dll*/
postquitmessage(0);
break;
default:
return (defwindowproc(hwnd, message,
wparam, lparam));
}
return (null);
}
程序4:部分windows程序源代码(子程序)
bool client(hwnd hwnd)/*客户机子程序*/
{
if (!make-skt(hwnd))/*建立套接字*/
return(false);
if (!set-select(hwnd,fd-connect))/*设置异步连接*/
return(false);
if (!connect-skt(hwnd))/*建立连接*/
return(false);
return(true);
}
bool receive-pkt(hwnd hwnd)/*接收数据子程序*/
{
hdc dc;
intlength;
int11,12,13;
charlinel,line2,line3;
count ++;/*循环计数器加1*/
if ((length=recv(s,lpbuffer,1024,0))==socket-error)
return(false); /*如果接收数据出错,则返回false*/
if (length==0) /*接收数据长度为零,表示连接中断*/
return(false);
if (dc=getdc(hwnd)) { /*接收数据成功,显示信息*/
11=wsprintf((lpstr) line1,"tcp echo client no.%d",count);
12=wsprintf((lpstr) line2,"received %d bytes", length);
13=wsprintf((lpstr) line3,"those are:%c,%c,%c,%c,%c,%c",
buffer,buffer,buffer,buffer,buffer,buffer
);
textout(dc, 10, 2, (lpstr) linel, 11);
textout(dc, 10, 22, (lpstr) line2, 12);
textout(dc, 10, 42, (lpstr) line3, 13);
releasedc(hwnd, dc);
}
return(true);
}
bool set-select(hwnd hwnd, long levent)/*异步选择子程序*/
{
if (wsaasyncselect(s,hwnd, um-sock, levent)==socket-error) {
alertuser(hwnd, "wsaasyncselect failed");
return (false);
}
return (true);
}
bool make-skt(hwnd hwnd)/*建立套接字子程序*/
{
if ((s=socket(af-inet,sock-type,0))==invalid-socket) {
alertuser(hwnd, "socket failed");
return (false);
}
return (true);
}
bool connect-skt(hwnd hwnd)/*建立连接子程序*/
{
memset((void*) &dst-addr, sizeof(dst-addr),0);
dst-addr.sin-family=af-inet;
dst-addr.sin-port=htons(userport);
dst-addr.sin-addr.s-addr=*((unsigned long *)hostnm.h-addr-list );
if (connect(s, (struct sockaddr *) & dst-addr,
sizeof(dst-addr))==socket-error) {
alertuser(hwnd, "connect failed");
return (false);
}
return (true);
}
bool send-pkt(hwnd hwnd, int len)/*发送数据子程序*/
{
int length;
if ((length=send(s,lpbuffer,len,0))==socket-error)
return (false);
else if (length !=len) {
alertuser(hwnd, "send length not match!");
return(false);
}
return (true);
}
我们用最简单的语句编制一个unix下基于bsd socket的服务器程序,它在建立连接后,只负责将收到的数据发回去,在连接断开后,服务器关闭套接字返回。要编制在windows下的服务器程序,可参照客户机程序,使用winsock的异步选择机制。
程序5:unix下服务器程序源代码
/*tcp/ip必要的头文件*/
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define userport 3333/*用户定义端口号,与客户机相同*/
#define host-ip-addr "166.111.8.80"/*我们的主机地址*/
main(int argc, char **argv)
{
char buf;/*buffer for sending and receiving data*/
struct sockaddr-in client;/*client address information*/
struct sockaddr-in server;/*server address information*/
int s;/*socket for accepting connections*/
int ns;/*socket connected to client*/
int namelen;/*length of client name*/
int pktlen;/*length of packet received or sended*/
if ((s = socket(af-inet,sock-stream, 0))<0) {
perror("socket()");
return;
}
/*bind the socket to the server address.*/
bzero((char*)&server, sizeof(server));
server.sin-len =sizeof(struct sockaddr-in);
server.sin-family=af-inet;
server.sin-port =htons(userport);
server.sin-addr.s-addr=inaddr-any;
if (bind(s, (struct sockaddr *)&server, sizeof(server)) <0) {
perror ("bind()");
return;
}
/*listen for connections. specify the backlog as 1. */
if (

核心期刊快速发表
Copyright@2000-2030 论文期刊网 Corporation All Rights Reserved.
《中华人民共和国信息产业部》备案号:ICP备07016076号;《公安部》备案号:33010402003207
本网站专业、正规提供职称论文发表和写作指导服务,并收录了海量免费论文和数百个经国家新闻出版总署审批过的具有国内统一CN刊号与国际标准ISSN刊号的合作期刊,供诸位正确选择和阅读参考,免费论文版权归原作者所有,谨防侵权。联系邮箱:256081@163.com