网络编程
来源:互联网 发布:为什么淘宝那么卡 编辑:程序博客网 时间:2024/04/29 15:00
1.编写一个基于tcp,也就是面向连接的服务器端的应用程序
TcpSrv.cpp
#include <WINSOCK2.H>
#include <stdio.h>
//编写一个基于tcp,也就是面向连接的服务器端的应用程序
void mian()
{
//我们用套接字编写网络应用程序的时候,首先应该加载套接字库
WORD wVersionRequested;
WSADATAwsaData;
interr;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0){
return;
}
if(LOBYTE(wsaData.wVersion)!=1||
HIBYTE(wsaData.wVersion)!=1){
WSACleanup();
return;
}
//创建套接字
SOCKETsockSrv=socket(AF_INET,SOCK_STREAM,0);
//接下来就应该将这个套接字绑定到一个本地地址和端口上
SOCKADDR_INaddrSrv;
//这里使用的是网络字节序
//htonl它是转换一个u_long类型,从主机字节序到TCP/IP网络字节序
//这个函数时转换一个u_short类型,从主机字节序到TCP/IP网络字节序
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
//地址族
addrSrv.sin_family=AF_INET;
//端口,端口号是两个字节的,所以应该用htons来转换
addrSrv.sin_port=htons(6000);
//绑定到一个本地地址和端口上
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//将套接字设置为监听模式,监听我们的连接请求
listen(sockSrv,5);
//在调用Accep函数时,定义一个地址结构体的变量,用来接收客户端的地址信息
SOCKADDR_INaddrClient;
//定义一个整形的变量,赋初始值,这个初始值就是结构体的长度
intlen=sizeof(SOCKADDR);
//这是一个死循环。因为作为服务器端程序来说,它需要不断的去等待
//客户端连接请求的到来,所以我们做一个循环,让它能够持续的运行下去
while(1)
{
//调用accept函数,去等待客户的连接到来并接受客户的连接请求
//去定义一个套接字的变量
SOCKETsockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
//当客户端的连接请求到来的时候,我们接受了这个连接请求
//建立了这个连接,同时返回了相对于这个连接的套接字
//那么接下来我们就可以进行通信了:
//我们可以向客户端发送数据,用send函数
char sendBuf[100];
//将一个数据格式化到buffer当中,将客户端的一个地址做一个
//格式化放到sendBuf当中
//inet_ntoa这个函数是接收in_addr类型的参数,然后返回一个
//点分十进制格式表示的IP地址的一个字符串
sprintf(sendBuf,"Welcome%s to http://www.sunxin.org",
inet_ntoa(addrClient.sin_addr));
//发送,这个套接字应该用建立连接相所对应的套接字,
//而不要用处于监听状态的套接字
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
//定义一个字符数组,用来接收
charrecvBuf[100];
recv(sockConn,recvBuf,100,0);
//将接收到的数据打印出来
printf("%s\n",recvBuf);
//关闭套接字,释放为套接字所分配的资源
closesocket(sockConn);
}
//接下来需要去链接一个库文件。Project->Setting->Link
//在Object/librarymodules中的内容移动到最后,然后添加ws2_32.lib
}
TcpClient.cpp
#include <WINSOCK2.H>
#include <stdio.h>
void mian()
{
//我们用套接字编写网络应用程序的时候,首先应该加载套接字库
WORDwVersionRequested;
WSADATAwsaData;
interr;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0){
return;
}
if(LOBYTE(wsaData.wVersion)!=1||
HIBYTE(wsaData.wVersion)!=1){
WSACleanup();
return;
}
SOCKETsockClient=socket(AF_INET,SOCK_STREAM,0);
//定义一个地址结构体的变量
SOCKADDR_INaddrSrv;
//然后对它的成员进行赋值,这里我们要设定服务器端它的IP地址
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));
charrecvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
send(sockClient,"Thisis zhangsan",strlen("This is zhangsan")+1,0);
closesocket(sockClient);
WSACleanup();
}
2.基于UDP的,也就是面向无连接的,网络应用程序的编写:
在UdpSrv.cpp中:
#include <WINSOCK2.H>
#include <stdio.h>
void mian()
{
WORD wVersionRequested;
WSADATAwsaData;
interr;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0){
return;
}
if(LOBYTE(wsaData.wVersion)!=1||
HIBYTE(wsaData.wVersion)!=1){
WSACleanup();
return;
}
//创建一个套接字,因为是基于UDP的,所以创建的是数据报套接字;
SOCKETsockSrv=socket(AF_INET,SOCK_DGRAM,0);
//用SOCKADDR_IN这个结构体定义一个变量;
SOCKADDR_INaddrSrv;
//然后对结构体的数据成员进行赋值;
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));
//定义地址结构的一个变量;
SOCKADDR_INaddrClient;
//然后定义一个变量,并给它赋一个初始值
intlen=sizeof(SOCKADDR);
//定义一个字符数组,用来接收数据;
charrecvBuf[100];
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
printf("%s\n",recvBuf);
closesocket(sockSrv);
WSACleanup();
}
在UdpClient.cpp中:
#include <WINSOCK2.H>
#include <stdio.h>
void mian()
{
//我们用套接字编写网络应用程序的时候,首先应该加载套接字库
WORD wVersionRequested;
WSADATAwsaData;
interr;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0){
return;
}
if(LOBYTE(wsaData.wVersion)!=1||
HIBYTE(wsaData.wVersion)!=1){
WSACleanup();
return;
}
SOCKETsockClient=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);
//发送数据
sendto(sockClient,"Hello",strlen("Hello")+1,0,
(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
closesocket(sockClient);
WSACleanup();
}
小总结:对于一个面向无连接的套接字编程来说非常简单,因为它不需要去建立连接。所有对客户端来说,在创建完套接字之后就可以直接用sendto去发送数据了。我们要注意的是基于TDP的和基于UDP的它们在使用接收数据和发送数据的时候调用的函数是不一样的,前者是用send和recv,后者是用的sendto和recvfrom这两个函数。
3.编写一个基于字符界面的聊天程序:
对于聊天类的软件我们通常会用基于UDP的方式来实现,因为UDP不需要建立连接而且没有数据确认和数据重传的机制,所以实施性较高,在聊天时即使丢失一些数据也不会影响信息的交流,我们可以根据上下文的语义推测出对方要表达的意思。
而在聊天中TCP面向连接,数据确认与重传的机制,将会影响聊天的效率。
在NetSrv.cpp中:
#include <WINSOCK2.H>
#include <stdio.h>
void mian()
{
//我们用套接字编写网络应用程序的时候,首先应该加载套接字库
WORD wVersionRequested;
WSADATAwsaData;
interr;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0){
return;
}
if(LOBYTE(wsaData.wVersion)!=1||
HIBYTE(wsaData.wVersion)!=1){
WSACleanup();
return;
}
//创建套接字
SOCKETsockSrv=socket(AF_INET,SOCK_DGRAM,0);
//对于服务器端,也就是我们这里的接收端首先需要绑定
//先定义一个地址结构体的变量
SOCKADDR_IN addrSrv;
//然后对地址结构体中的成员进行赋值
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_port=htons(6000);
//将套接字和本地主机的地址和端口进行绑定
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//定义字符数组接收信息和发送信息和存放中间数据;
charrecvBuf[100];
charsendBuf[100];
char tempBuf[200];
//我们接收的时候需要获取和我们通信的这一方的地址信息
//先定义一个地址结构体的变量;
SOCKADDR_INaddrClient;
//定义一个长度,初始化的值是地址结构体的长度
intlen=sizeof(SOCKADDR);
//做一个while循环,保证我们通信的过程可以不断的继续下去;
while(1)
{
//接收数据
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
//当我们收到数据的时候,做一个判断,判断这个数据的第一个字符
//是不是‘q’,如果是‘q’表面跟我们通讯的这一方它想退出,既然
//它想退出,那么我们给对方也发送一个字符‘q’
if('q'==recvBuf[0])
{
sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);
printf("Charend!\n");
break;
}
//如果不是‘q’说明我们收到了客户发过来的数据,我们可以将这个
//数据做一个格式化,然后放到tempBuf当中
//将对方的IP地址取出来
sprintf(tempBuf,"%ssay : %s",inet_ntoa(addrClient.sin_addr),recvBuf);
//将数据打印输出
printf("%s\n",tempBuf);
//我们应该根据它的输出来回复一个信息,这个回复信息,我们希望通过
//标准的输入设备来获取,也就是说从用户的键盘输入,可以调用gets()函数
//可以从标准输入流当中获取一行数据,当我们通过键盘输入一行数据之后
//一回车,这个数据就放到了指定的字符指针所指向的内存buffer当中
//接下来我们可以将输入发送到客户端。
printf("pleaseinput data:\n");
gets(sendBuf);
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);
}
closesocket(sockSrv);
WSACleanup();
}
在NetClient.cpp中:
#include <WINSOCK2.H>
#include <stdio.h>
void mian()
{
//我们用套接字编写网络应用程序的时候,首先应该加载套接字库
WORD wVersionRequested;
WSADATAwsaData;
interr;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0){
return;
}
if(LOBYTE(wsaData.wVersion)!=1||
HIBYTE(wsaData.wVersion)!=1){
WSACleanup();
return;
}
SOCKETsockClient=socket(AF_INET,SOCK_DGRAM,0);
//对于基于UDP的客户端来说,也就是发送端,它不需要去绑定
//但是,它需要去设定你要发送到对方的机器的地址信息
SOCKADDR_INaddrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
charrecvBuf[100];
charsendBuf[100];
chartempBuf[200];
//要定义一个变量,在我们接收一个数据的时候要返回地址结构的长度
//我们用这个变量去接收所返回的地址结构的长度,这个变量必须经过初始化
intlen=sizeof(SOCKADDR);
while(1)
{
printf("pleaseinput 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("Charend!\n");
break;
}
sprintf(tempBuf,"%ssay: %s",inet_ntoa(addrSrv.sin_addr),recvBuf);
printf("%s\n",tempBuf);
}
//关闭套接字
closesocket(sockClient);
//终止对套接字库的使用
WSACleanup();
}
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 网络编程
- 二叉树的顺序存储
- WPF中根据元素名称查找子元素
- FPGA AD0809 Verilog implement
- C语言函数指针基础
- GOP Overview
- 网络编程
- vs2005安装cocos2d-x模版(版本cocos2d-2.1rc0-x-2.1.3)
- Android里Service的bindService()和startService()混合使用深入分析
- Maya: 菜单 编辑NURBS >修剪工具
- 南阳理工ACM 22 素数求和问题
- java jdbc访问数据库步骤
- Storm 集群安装
- Quartz的cron表达式
- HDU 1709 母函数