第十四课网络编程
int WSAStartup (
WORD wVersionRequested,
LPWSADATA lpWSAData
);
wVersionRequested参数用语指定准备加载得Winsock 库得版本,高委字节指定所需要得Winsock库得副版本,而地位字节则是主版本,课用MAKEWORD(x,y)x是高委字节,y是低位字节方便得获得wVersionRequested得正确值。lpWSAData参数是指向WSADATA结构得指针,WSAStartup用其加载得库版本有关得信息填在这个结构中。
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;//家丁同时最多课打开多少桃结子和数据报得最大长度。而知道数据库得最大长度应该通过WSAEnumProtocols来查询协议信息。同时最多可打开桃结子得书目不是固定得,取决与物理内存得大小
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
} WSADATA, FAR * LPWSADATA;
看MSDN中得例子。
SOCKET socket ( int af, int type, int protocol); 第一个参数af指定地址族,对于TCP/IP他只能是AF_INET 第二个参数指定Socket类型SOCK_STREAM流式套节字 SOCK_DGRAM数据报套节字
,第三个参数一般选0,表示为 特定地址家族选定合适得协议。
注意网络上传输必须要用网络字节序,如果不是,则一定要通过 函数 或者数据结构强制 转换成 网络字节 序流法。
SOCKET sockSrv=socket(AF_INET,SOCK_STRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5);
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"welcome%s to http://www.sunxin.org.",inet_ntoa(addrClient,sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s/n",recvBuf);
closesocket(sockConn);}
int bind (
SOCKET s,
const struct sockaddr FAR* name,
int namelen
);
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
sa_family 指定该地址家族,在这里必须设为AF_INET.sa_data 仅仅式表示要求一块内存分配区,起到占位得作用,一般用 sockaddr_in 来代替sockaddr
int listen (
SOCKET s,
int backlog //等待连接得最大队列长度。
);
#最后要在Link 中连接库 ws2_32.lib
#include <winsock2.h>
#include <stdio.h>
void main(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
//以下部分为自己添加
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);//网络字节序
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//求字节长度
char recvBuf[100];
recv(sockClient,recvBuf,100,0);//100为长度,0为标记。
printf("%s/n",recvBuf);
send(sockClient,"This is lisi ",strlen("this is lisi ")+1,0);
closesocket(sockClient);
WSACleanup();
} //客户断 完成
//UDP服务断
//UDP客户断
#include <winsock2.h>
#include <stdio.h>
void main(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
//以下部分为自己添加得
SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//将十进制转化成UL类型得网络字节序
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
sendto(sockClient,"Hello",strlen("Hello")+1,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
closesocket(sockClient);
WSACleanup();
}
UDP聊天
如果采用TCP 三次握手由于空闲时间比较大。 连接应该保持呢还是先断开等到对方说话得时候再建立连接呢?
最后一个 双向聊天 晓程序
//服务器端, 注意连接WS2_32.lib
#include <winsock2.h>
#include <stdio.h>
void main(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
//以下部分为自己添加 得
SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)
{
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
if('q'==recvBuf[0])
{
sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);
printf("chat end!");
break;
}
sprintf(tempBuf,"%s say: %s",inet_ntoa(addrClient.sin_addr),recvBuf);
printf("%s/n",tempBuf);
printf("please input data:/n");
gets(sendBuf);
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);
}
closesocket(sockSrv);
WSACleanup();
}
//客户断
#include <winsock2.h>
#include <stdio.h>
void main(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
//以下部分为自己田间
SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
int len =sizeof(SOCKADDR);
while(1)
{
printf("please input data:/n");
gets(sendBuf);
sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,
(SOCKADDR*)&addrSrv,len);
recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);
if('q'==recvBuf[0])
{
sendto(sockClient,"q",strlen("q")+1,0,(SOCKADDR*)&addrSrv,len);
printf("chat end!/n");
break;
}
sprintf(tempBuf,"%s say :%s",inet_ntoa(addrSrv.sin_addr),recvBuf);
printf("%s/n",tempBuf);
}
closesocket(sockClient);
WSACleanup();
}
int WSAStartup (
WORD wVersionRequested,
LPWSADATA lpWSAData
);
wVersionRequested参数用语指定准备加载得Winsock 库得版本,高委字节指定所需要得Winsock库得副版本,而地位字节则是主版本,课用MAKEWORD(x,y)x是高委字节,y是低位字节方便得获得wVersionRequested得正确值。lpWSAData参数是指向WSADATA结构得指针,WSAStartup用其加载得库版本有关得信息填在这个结构中。
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;//家丁同时最多课打开多少桃结子和数据报得最大长度。而知道数据库得最大长度应该通过WSAEnumProtocols来查询协议信息。同时最多可打开桃结子得书目不是固定得,取决与物理内存得大小
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
} WSADATA, FAR * LPWSADATA;
看MSDN中得例子。
SOCKET socket ( int af, int type, int protocol); 第一个参数af指定地址族,对于TCP/IP他只能是AF_INET 第二个参数指定Socket类型SOCK_STREAM流式套节字 SOCK_DGRAM数据报套节字
,第三个参数一般选0,表示为 特定地址家族选定合适得协议。
注意网络上传输必须要用网络字节序,如果不是,则一定要通过 函数 或者数据结构强制 转换成 网络字节 序流法。
SOCKET sockSrv=socket(AF_INET,SOCK_STRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5);
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"welcome%s to http://www.sunxin.org.",inet_ntoa(addrClient,sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s/n",recvBuf);
closesocket(sockConn);}
int bind (
SOCKET s,
const struct sockaddr FAR* name,
int namelen
);
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
sa_family 指定该地址家族,在这里必须设为AF_INET.sa_data 仅仅式表示要求一块内存分配区,起到占位得作用,一般用 sockaddr_in 来代替sockaddr
int listen (
SOCKET s,
int backlog //等待连接得最大队列长度。
);
#最后要在Link 中连接库 ws2_32.lib
#include <winsock2.h>
#include <stdio.h>
void main(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
//以下部分为自己添加
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);//网络字节序
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//求字节长度
char recvBuf[100];
recv(sockClient,recvBuf,100,0);//100为长度,0为标记。
printf("%s/n",recvBuf);
send(sockClient,"This is lisi ",strlen("this is lisi ")+1,0);
closesocket(sockClient);
WSACleanup();
} //客户断 完成
//UDP服务断
//UDP客户断
#include <winsock2.h>
#include <stdio.h>
void main(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
//以下部分为自己添加得
SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//将十进制转化成UL类型得网络字节序
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
sendto(sockClient,"Hello",strlen("Hello")+1,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
closesocket(sockClient);
WSACleanup();
}
UDP聊天
如果采用TCP 三次握手由于空闲时间比较大。 连接应该保持呢还是先断开等到对方说话得时候再建立连接呢?
最后一个 双向聊天 晓程序
//服务器端, 注意连接WS2_32.lib
#include <winsock2.h>
#include <stdio.h>
void main(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
//以下部分为自己添加 得
SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)
{
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
if('q'==recvBuf[0])
{
sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);
printf("chat end!");
break;
}
sprintf(tempBuf,"%s say: %s",inet_ntoa(addrClient.sin_addr),recvBuf);
printf("%s/n",tempBuf);
printf("please input data:/n");
gets(sendBuf);
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);
}
closesocket(sockSrv);
WSACleanup();
}
//客户断
#include <winsock2.h>
#include <stdio.h>
void main(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
//以下部分为自己田间
SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
int len =sizeof(SOCKADDR);
while(1)
{
printf("please input data:/n");
gets(sendBuf);
sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,
(SOCKADDR*)&addrSrv,len);
recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);
if('q'==recvBuf[0])
{
sendto(sockClient,"q",strlen("q")+1,0,(SOCKADDR*)&addrSrv,len);
printf("chat end!/n");
break;
}
sprintf(tempBuf,"%s say :%s",inet_ntoa(addrSrv.sin_addr),recvBuf);
printf("%s/n",tempBuf);
}
closesocket(sockClient);
WSACleanup();
}