vc++Socket编程

IP相当于一个公司的总机电话,端口相当于分机号码.
OSI:物理层-二进制传输,数据链路层-介质访问(接入),网络层-寻址和最短路径,传输层-端到端的连接,会话层-主机间通信,表示层-数据表示,应用层-处理网络应用.

OSI各层所使用的协议.
1.应用层:远程登陆协议Telnet,文件传世协议FTP,超文本传输协议HTTP,域名服务DNS,简单邮件传输协议SMTP,邮局协议POP3等.
2.传输层:传输控制协议TCP,用户数据报协议UDP.
  TCP:面向连接的可靠的传输协议.
  UDP:是无连接的,不可靠的传输协议.
3.网络层:网际协议IP,Internet互联网控制报文协议ICMP,Internet组管理协议IGMP.


一台计算机要发送数据到另一台计算机,数据首先必须打包,打包的过程称为封装.
封装就是在数据前面加上特定的协议头部.

TCP/IP模型包括四个层次
4.应用层   5.6.7
3.传输层   4
2.网络层   3
1.网络接口 1.2

Socket,使程序员可以很方便的访问TCP/IP,从而开发各种网络应用程序.

TCP/IP协议使用16位和32位整数的高位先存格式.

基于TCP(面向连接)的Socket编程
服务器端程序:
1.创建套接字(socket).
2.将套接字绑定到一个本地地址和端口上(bind).
3.将套接字设为监听模式,准备接受客户请求(listen).
4.等待客户请求到来,请求到来后,接受请求,返回一个新的对应于此次连接的套接字.
5.用返回的套接字和客户端进行通信(send/recv).
6.返回,等待另一个客户请求.
7.关闭套接字.

客户端程序:
1.创建套接字(socket).
2.向服务器发出连接请求(connect).
3.和服务器端进行通信(send/recv).
4.关闭套接字.


基于UDP(面向无连接)的Socket编程
服务器(接收端)程序:
1.创建套接字(socket).
2.将套接字绑定到一个本地地址和端口上(bind).
3.等待接收数据(recvfrom).
4.关闭套接字.

客户端(发送端)程序:
1.创建套接字(socket).
2.向服务器发送数据(sendto).
3.关闭套接字.


编程时,应该包含的头文件Winsock2.h

link中要加入ws2_32.lib

main函数要包含套接字库程序

/*编写网络程序都要用的链接套接字库*/


 WORD wVersionRequested;
 WSADATA wsaData;
 int err;
 wVersionRequested = MAKEWORD( 1, 1 );/*请求版本号的winsocket库*/
 err = WSAStartup( wVersionRequested, &wsaData );
 if ( err != 0 )
 {
  return;
 }
 if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )
 {
  WSACleanup( );
  return;
 }
/*编写网络程序都要用的链接套接字库*/

 

htonl(): 将主机的无符号长整形数转换成网络字节顺序。

代码
服务器代码:
#include
<Winsock2.h>
#include
<stdio.h>


void main()
{
/*编写网络程序都要用的链接套接字库*/


WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );/*请求版本号的winsocket库*/
err = WSAStartup( wVersionRequested,
&wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}

/*编写网络程序都要用的链接套接字库*/

SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); //基于http的都用流套接字
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",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);
}
}
 
 
客户端代码:
#include<Winsock2.h>
#include<stdio.h>


void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );/*请求版本号的winsocket库*/
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
  return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )
{
  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"); //连接服务器的IP(这里用于本机测试)
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,"zhang san !",strlen("zhang san !")+1,0);

//关闭套接字
closesocket(sockClient);
WSACleanup();
}


 

 

posted @ 2010-11-28 11:12  arrow'  阅读(1127)  评论(0编辑  收藏  举报