socket局域网聊天软件c语言
⑴ 毕业论文《基于socket 的局域网聊天工具》,要求C++语音编写,要有程序,能实现,有文档……
“对图中的那些函数,我这里稍加解释一下。”
intWSAStartup(WORDwVersionRequested,LPWSADATAlpWSAData);
功能是初始化WindowsSocketDll,在Windows下必须使用它。
参数:
“wVersionRequested”表示版本,可以是1.1、2.2等;
“lpWSAData”指向WSADATA数据结构的指针。
intsocket(intfamily,inttype,intprotocol);
功能是建立Socket,返回以后会用到的Socket值。如果错误,返回-1。
参数:
“intfamily”参数指定所要使用的通信协议,取以下几个值:AF_UNIX(Unix内部协议)、AF_INET(Internet协议)、AF_NSXerox(NS协议)、AF_IMPLINK(IMP连接层),在Windows下只能把“AF”设为“AF_INET”;
“inttype”参数指定套接字的类型,取以下几个值:SOCK_STREAM(流套接字)、SOCK_DGRAM(数据报套接字)、SOCK_RAW(未加工套接字)、SOCK_SEQPACKET(顺序包套接字);
“intprotocol”参数通常设置为0。
intbind(intsockfd,structsockaddr*my_addr,intaddrlen);
功能是把套接字和机器上一定的端口关联起来。
参数:
“sockfd”是调用socket()返回的套接字值;
“my_addr”是指向数据结构structsockaddr的指针,它保存你的地址,即端口和IP地址信息;
“addrlen”设置为sizeof(structsockaddr)。
intlisten(intsockfd,intbacklog);
功能是服务端监听一个端口,直到accept()。在发生错误时返回-1。
参数:
“sockfd”是调用socket()返回的套接字值;
“backlog”是允许的连接数目。大多数系统的允许数目是20,也可以设置为5到10。
intconnect(intsockfd,structsockaddr*serv_addr,intaddrlen);
功能是客户端连接服务端监听的端口。
参数:
“sockfd”是调用socket()返回的套接字值;
“serv_addr”保存着目的地端口和IP地址的数据结构structsockaddr;
“addrlen”设置为sizeof(structsockaddr)。
intaccept(intsockfd,void*addr,int*addrlen);
功能是服务端接受客户端的连接请求,并返回一个新的套接字,以后服务端的数据传输就使用这个新的套接字。如果有错误,返回-1。
参数:
“sockfd”是和listen()中一样的套接字值;
“addr”是个指向局部的数据结构sockaddr_in的指针;
“addrlen”设置为sizeof(structsockaddr_in)。
intsend(intsockfd,constvoid*msg,intlen,intflags);
intrecv(intsockfd,void*buf,intlen,unsignedintflags);
功能是用于流式套接字或数据报套接字的通讯,我们数据的真正传输就由它们完成。
参数:
“sockfd”是发/收数据的套接字值;
“msg”指向你想发送的数据的指针;
“buf”是指向接收数据存放的地址;
“len”是数据的长度;
“flags”设置为0。
intsendto(intsockfd,constvoid*msg,intlen,unsignedintflags,conststructsockaddr*to,inttolen);
intrecvfrom(intsockfd,void*buf,intlen,unsignedintflags,structsockaddr*from,int*fromlen);
功能和send、recv类似,不过是用于无连接数据报套接字的传输。
intclosesocket(intsockfd)
功能是关闭套接字。
参数“sockfd”为要关闭的套接字值。
程序:
“这里的目的是让大家对Socket编程有个整体了解。不用怕,程序我会详细解释的,首先是服务端的程序。其流程是:
socket()→bind()→listen→accept()→recv()/send()→closesocket()
具体代码如下:”
★
#include<stdio.h>
#include<winsock.h>
#pragmacomment(lib,"Ws2_32")
#defineMYPORT830/*定义用户连接端口*/
#defineBACKLOG10/*多少等待连接控制*/
intmain()
{
intsockfd,new_fd;/*定义套接字*/
structsockaddr_inmy_addr;/*本地地址信息*/
structsockaddr_intheir_addr;/*连接者地址信息*/
intsin_size;
WSADATAws;
WSAStartup(MAKEWORD(2,2),&ws);//初始化WindowsSocketDll
//建立socket
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
//如果建立socket失败,退出程序
printf("socketerror ");
exit(1);
}
//bind本机的MYPORT端口
my_addr.sin_family=AF_INET;/*协议类型是INET*/
my_addr.sin_port=htons(MYPORT);/*绑定MYPORT端口*/
my_addr.sin_addr.s_addr=INADDR_ANY;/*本机IP*/
if(bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr))==-1)
{
//bind失败,退出程序
printf("binderror ");
closesocket(sockfd);
exit(1);
}
//listen,监听端口
if(listen(sockfd,BACKLOG)==-1)
{
//listen失败,退出程序
printf("listenerror ");
closesocket(sockfd);
exit(1);
}
printf("listen...");
//等待客户端连接
sin_size=sizeof(structsockaddr_in);
if((new_fd=accept(sockfd,(structsockaddr*)&their_addr,&sin_size))==-1)
{
printf("accepterror ");
closesocket(sockfd);
exit(1);
}
printf(" accept! ");
//有连接,发送ww0830字符串过去
if(send(new_fd,"ww0830 ",14,0)==-1)
{
printf("senderror");
closesocket(sockfd);
closesocket(new_fd);
exit(1);
}
printf("sendok! ");
//成功,关闭套接字
closesocket(sockfd);
closesocket(new_fd);
return0;
}
对服务端程序的流程概括:
先是初始化WindowsSocketDll:WSAStartup(MAKEWORD(2,2),&ws);
然后建立Socket:sockfd=socket(AF_INET,SOCK_STREAM,0)
再bind本机的MYPORT端口:
my_addr.sin_family=AF_INET;/*协议类型是INET*/
my_addr.sin_port=htons(MYPORT);/*绑定MYPORT端口*/
my_addr.sin_addr.s_addr=INADDR_ANY;/*本机IP*/
bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr))
接下来监听端口:listen(sockfd,BACKLOG)
如果有客户端的连接请求,接收它:new_fd=accept(sockfd,(structsockaddr*)&their_addr,&sin_size)
最后发送ww0830字符串过去:send(new_fd,"ww0830 ",14,0)
收尾工作,关闭socket:closesocket(sockfd);closesocket(new_fd);”
编译、执行,就会一直监听830端口
客户端程序了。其流程是:
socket()→connect()→send()/recv()→closesocket()
比服务端更简单吧!其实现代码如下:”
★
#include<stdio.h>
#include<stdio.h>
#include<winsock.h>
#pragmacomment(lib,"Ws2_32")
#definePORT830/*客户机连接远程主机的端口*/
#defineMAXDATASIZE100/*每次可以接收的最大字节*/
intmain(intargc,char*argv[])
{
intsockfd,numbytes;
charbuf[MAXDATASIZE];
structsockaddr_intheir_addr;/*对方的地址端口信息*/
if(argc!=2)
{
//需要有服务端ip参数
fprintf(stderr,"usage:clienthostname ");
exit(1);
}
WSADATAws;
WSAStartup(MAKEWORD(2,2),&ws);//初始化WindowsSocketDll
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
//如果建立socket失败,退出程序
printf("socketerror ");
exit(1);
}
//连接对方
their_addr.sin_family=AF_INET;/*协议类型是INET*/
their_addr.sin_port=htons(PORT);/*连接对方PORT端口*/
their_addr.sin_addr.s_addr=inet_addr(argv[1]);/*连接对方的IP*/
if(connect(sockfd,(structsockaddr*)&their_addr,sizeof(structsockaddr))==-1)
{
//如果连接失败,退出程序
printf("conneterror ");
closesocket(sockfd);
exit(1);
}
//接收数据,并打印出来
if((numbytes=recv(sockfd,buf,MAXDATASIZE,0))==-1)
{
//接收数据失败,退出程序
printf("recverror ");
closesocket(sockfd);
exit(1);
}
buf[numbytes]='