标签:
服务器端代码server.cpp:
1 #include <stdio.h> 2 #include <WinSock2.h> 3 #pragma comment(lib,"ws2_32.lib") //加载ws2_32.dll 4 5 int main() 6 { 7 //初始化DLL 8 /************************************************************************/ 9 /*调用WSAStartup()函数进行初始化,并指明要使用的版本号 */ 10 /************************************************************************/ 11 WSADATA wsaData; 12 WSAStartup(MAKEWORD(2,2),&wsaData); //主版本号为2,副版本号为2,返回0x0202 13 14 //创建套接字 15 /************************************************************************/ 16 /*Windows下使用的socket()函数来创建套接字,原型为: 17 SOCKET socket(int af,int type,int protocol); 18 1)af为地址族(Address Family),也就是IP地址类型,常用的有AF_INET(表示IPv4地址)和AF_INET6(表示IPv6地址)。 19 AF是“Address Family”的简写,INET是“Internet”的简写。 20 也可以使用PF前缀,PF是“Protocol Family”的简写,它和AF是一样的。PF_INET等价于AF_INET,PF_INET6等价于AF_INET6 21 2)type为数据传输方式,常用的有SOCK_STREAM(面向连接的数据传输方式)和SOCK_DGRAM(无连接的数据传输方式) 22 3)protocol表示传输协议,常用的有IPPROTO_TCP和IPPTOTO_UDP,分别表示TCP传输协议和UDP传输协议 23 */ 24 /************************************************************************/ 25 SOCKET servSock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); //创建TCP套接字,返回SOCKET类型的句柄 26 27 28 //绑定套接字 29 /************************************************************************/ 30 /*bind()函数的原型为: 31 int bind(SOCKET sock,const struct sockaddr *addr,int addrlen); //Windows 32 1)sock为socket文件句柄,addr为sockaddr结构体变量的指针,addrlen为addr变量的大小,可由sizeof()计算得出 33 2)这里使用sockaddr_in结构体,然后再强制转换为SOCKADDR类型。可以认为,SOCKADDR是一种通用的结构体,可以用来 34 保存多种类型的IP地址和端口号,而sockaddr_in是专门用来保存IPv4地址的结构体。 35 */ 36 /************************************************************************/ 37 sockaddr_in sockAddr; 38 memset(&sockAddr,0,sizeof(sockAddr)); //每个字节都用0填充 39 sockAddr.sin_family=PF_INET; //使用IPv4地址 40 sockAddr.sin_addr.s_addr=inet_addr("127.0.0.1"); //具体的IP地址(s_addr是一个整数, 41 //而IP地址是一个字符串,所以需要inet_addr()函数进行转换) 42 sockAddr.sin_port=htons(1234); //端口 43 //(理论上端口号的取值范围为0-65536,但0-1023的端口一般由系统分配给特定的服务程序, 44 //例如Wed服务的端口号为80,FTP服务的端口号为21,所以我们的程序要尽量在1024-65536之间分配端口号 45 //端口号需要用htons()函数转换) 46 bind(servSock,(SOCKADDR*)&sockAddr,sizeof(SOCKADDR)); //将套接字和IP、端口绑定 47 48 //进入监听状态 49 /************************************************************************/ 50 /*对于服务端程序,使用bind()绑定套接字后,还需要使用listen()函数让套接字进入被动监听 51 状态,再调用accept()函数,就可以随时响应客户端的请求了 52 通过listen()函数可以让套接字进入被动监听状态,它的原型为: 53 int listen(SOCKET sock,int backlog); //Windows 54 sock为需要进入监听状态的套接字,backlog为请求队列的最大长度 55 */ 56 /************************************************************************/ 57 listen(servSock,20); 58 59 //接收客户端请求 60 /************************************************************************/ 61 /*当套接字处于监听状态时,可以通过accept()函数来接收客户端请求,它的原型为: 62 SOCKET accept(SOCKET sock,struct sockaddr *addr,int *addrlen); //Windows 63 sock为服务端套接字,addr为sockaddr结构体变量,addrlen为参数addr的长度,可由sizeof()求得。 64 accept()返回一个新的套接字来和客户端通信,addr保存了客户端的IP地址和端口号,而sock是服务器端的套接字。 65 后面和客户端通信时,要使用这个新生成的套接字,而不是原来服务器端的套接字。 66 67 listen()只是让套接字进入监听状态,并没有真正接收客户端请求,listen()后面的代码会继续执行,直到 68 遇到accept()。accept()会阻塞程序执行(后面代码不能被执行),直到有新的请求到来。 69 */ 70 /************************************************************************/ 71 SOCKADDR clntAddr; 72 int nSize=sizeof(SOCKADDR); 73 SOCKET clntSock=accept(servSock,(SOCKADDR*)&clntAddr,&nSize); 74 75 //向客户端发送数据 76 /************************************************************************/ 77 /*从服务器端发送数据使用send()函数,它的原型为: 78 int send(SOCKET sock,const char *buf,int len,int flags); 79 sock为要发送数据的套接字,buf为要发送的数据的缓冲区地址,len为要发送的数据的字节数,flags为要 80 发送数据时的选项。 81 最后的flags参数一般设置为0或NULL。 82 */ 83 /************************************************************************/ 84 char *str="Hello World!"; 85 send(clntSock,str,strlen(str)+sizeof(char),NULL); 86 87 88 //关闭套接字 89 closesocket(clntSock); 90 closesocket(servSock); 91 92 //终止DLL的使用 93 WSACleanup(); 94 95 return 0; 96 }
客户端代码client.cpp:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <WinSock2.h> 4 #pragma comment(lib,"ws2_32.lib") //加载ws2_32.dll 5 6 7 int main() 8 { 9 //初始化DLL 10 WSADATA wsaData; 11 WSAStartup(MAKEWORD(2,2),&wsaData); 12 13 //创建套接字 14 SOCKET sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); 15 16 //向服务器发起请求 17 sockaddr_in sockAddr; 18 memset(&sockAddr,0,sizeof(sockAddr)); //每个字节都用0填充 19 sockAddr.sin_family=PF_INET; 20 sockAddr.sin_addr.s_addr=inet_addr("127.0.0.1"); 21 sockAddr.sin_port=htons(1234); 22 23 /************************************************************************/ 24 /*connect()函数用来建立连接,它的原型为: 25 int connect(SOCKET sock,const struct sockaddr *serv_addr,int addrlen); //Windows 26 */ 27 /************************************************************************/ 28 connect(sock,(SOCKADDR*)&sockAddr,sizeof(SOCKADDR)); 29 30 //接收服务器传回的数据 31 char szBuffer[MAXBYTE]={0}; 32 33 /************************************************************************/ 34 /*在客户端接收数据使用recv()函数,它的原型为: 35 int recv(SOCKET sock,char *buf,int len,int flags); 36 */ 37 /************************************************************************/ 38 recv(sock,szBuffer,MAXBYTE,NULL); 39 40 //输出接收到的数据 41 printf("Message from server: %s\n",szBuffer); 42 43 //关闭套接字 44 closesocket(sock); 45 46 //终止使用DLL 47 WSACleanup(); 48 49 system("pause"); 50 51 return 0; 52 }
标签:
原文地址:http://www.cnblogs.com/chunlanse2014/p/4989828.html