网络编程
基于TCP的socket编程:
基于UDP的socket编程:
1.基于TCP连接的服务器客户端程序
新建一个win32 console application ,工程名为TCPSrv,再添加一个源程序,取名也为TCPSrv.
服务端程序:
因为要用到win32 套接字的函数,所以要在头文件中包含Winsock2.h这个头文件,并在project -> Setting -> Link -> Object/library modules中添加ws2_32.lib 库文件。编辑TCPSrv.cpp文件:
//TCPSrv.cpp
#include <stdio.h>
#include <Winsock2.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1
HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1
{
WSACleanup( );//终止对winsocket的使用
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
//创建一个服务端的套接字
SOCKADDR_IN addrSrv;//定义一个地址结构体变量
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//对这个地址结构体的成员赋值
//将主机字节序转换成u_long类型的网络字节序
addrSrv.sin_family=AF_INET;//指定地址簇
addrSrv.sin_port=htons(6000);//指定端口号
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//绑定套接字
listen(sockSrv,5);//设置套接字为监听模式,5代表等待连接队列的最大为5
SOCKADDR_IN addrClient;//用来接收客户端的地址信息
int len=sizeof(SOCKADDR);//获得这个结构体的长度
while(1) //保证能够不断接收客户端请求的到来
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
//接收套接字的请求
char sendBuf[100];//定义一个Buf字符数组
sprintf(sendBuf,"Welcom %s to http://www.luowei.org",
inet_ntoa(addrClient.sin_addr));//将要发送的数据格式化到Buf当中
//inet_ntoa接收一个in_addr类型的参数,返回一个点分十进制表示的IP地址的字符串
send(sockConn,sendBuf,strlen(sendBuf)+1,0);//发送数据
char recvBuf[100];//定义一个用来接收的字符数组
recv(sockConn,recvBuf,100,0);//接收数据
printf("%s\n",recvBuf);
closesocket(sockConn);//关闭套接字,释放为这个套接字所分配的资源
}
}
客户端程序:
在Workspace 'TCPSrv'上点右键 -> Add New Project To Workspace… , 选择win32 console application ,工程名为TCPClient,目录放到TCPClient下,再添加一个源程序,取名也为TCPClient。编辑:
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1
HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1
{
WSACleanup( );//终止对winsocket的使用
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);
printf("%s\n",recvBuf);
send(sockClient,"This is luowei_Client",strlen("This is luowei_Client")+1,0);
//发送消息
closesocket(sockClient);
WSACleanup();//终止对套接字库的使用
}
运行,OK !
2.基于TCP连接的服务器客户端程序
新建一个win32 console application ,工程名为UDPSrv,再添加一个源程序,取名也为UDPSrv.
服务端程序:
因为要用到win32 套接字的函数,所以要在头文件中包含Winsock2.h这个头文件,并在project -> Setting -> Link -> Object/library modules中添加ws2_32.lib 库文件。编辑UDPSrv.cpp文件:
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1
HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1
{
WSACleanup( );//终止对winsocket的使用
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
//创建一个服务端的套接字
SOCKADDR_IN addrSrv;//定义一个地址结构体变量
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
//对这个地址结构体的成员赋值
//htonl将主机字节序转换成u_long类型的网络字节序
addrSrv.sin_family=AF_INET;//指定地址簇
addrSrv.sin_port=htons(6000);//指定端口号
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
SOCKADDR_IN addrClient;//定义一个地址结构变量,用来接收发送方的地址信息
int len=sizeof(SOCKADDR);
char recvBuf[100];
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
//接收数据
printf("%s\n",recvBuf);
closesocket(sockSrv);
WSACleanup();
}
客户端程序:
在Workspace 'UDPSrv'上点右键 -> Add New Project To Workspace… , 选择win32 console application ,工程名为UDPClient,目录放到UDPClient下,再添加一个源程序,取名也为UDPClient。编辑:
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1
HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1
{
WSACleanup( );//终止对winsocket的使用
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");
//对这个地址结构体的成员赋值
//hto将主机字节序转换成u_long类型的网络字节序
addrSrv.sin_family=AF_INET;//指定地址簇
addrSrv.sin_port=htons(6000);//指定端口号
sendto(sockClient,"Hello",strlen("Hello")+1,0,
(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
closesocket(sockClient);
WSACleanup();
}
3.简单的聊天程序
新建一个win32 console application ,工程名为NetSrv,再添加一个源程序,取名也为NetSrv.
服务端程序:
因为要用到win32 套接字的函数,所以要在头文件中包含Winsock2.h这个头文件,并添加ws2_32.lib 库文件。编辑NetSrv.cpp文件:
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1
HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1
{
WSACleanup( );//终止对winsocket的使用
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
//创建一个服务端的套接字
SOCKADDR_IN addrSrv;//定义一个地址结构体变量
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
//对这个地址结构体的成员赋值
//htonl将主机字节序转换成u_long类型的网络字节序
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])//如果接收的字符是q
{
sendto(sockSrv,"q",strlen("q")+1,0,
(SOCKADDR*)&addrClient,len);
printf("Chat end!\n");
break;//退出循环
}
sprintf(tempBuf,"%s say: %s",inet_ntoa(addrClient.sin_addr),recvBuf);
printf("%s\n",tempBuf);//把接收的数据放置tempBuf当中,并打印输出
printf("Please input data:\n");
gets(sendBuf);//读取一行数据
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);
//把数据发送给客户端
}
closesocket(sockSrv);
WSACleanup();
}
客户端程序:
在Workspace 'NetSrv'上点右键 -> Add New Project To Workspace… , 选择win32 console application ,工程名为NetClient,目录放到NetClient下,再添加一个源程序,取名也为NetClient。编辑:
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1
HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1
{
WSACleanup( );//终止对winsocket的使用
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");
//对这个地址结构体的成员赋值
//htonl将主机字节序转换成u_long类型的网络字节序
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();
}
运行 ! OK !!!