windows环境socket编程
- 格式:doc
- 大小:31.50 KB
- 文档页数:3
242return 0;}程序的工作组流程如下。
•初始化Windows Sockets环境。
•创建完成端口对象CompletionPort。
•根据当前计算机中CPU的数量创建工作线程,并将新建的完成端口对象CompletionPort 作为线程的参数。
•创建监听Socket Listen,并将其绑定到本地地址的9990端口。
•在Socket Listen上进行监听。
•在while循环处理来自客户端的连接请求,接受连接,并将得到的与客户端进行通信的Socket Accept保存到PER_HANDLE_DATA结构体对象PerHandleData中。
将Socket Accept与前面的端口CompletionPort相关联。
•在Socket Accept上调用WSARecv()函数,异步接收Socket上来自客户端的数据。
WSARecv()函数立即返回,此时Socket Accept上不一定有客户端发送来的消息。
在工作线程中会检测完成端口对象的状态,并接收来自客户端的数据,再将这些数据发送回客户端程序。
一、选择题1.下面不属于Socket编程模型的是()。
A.Select模型B.WSAAsyncSelect模型C.WSAEventSelect模型D.完成例程模型2.下面模型使用线程池处理异步I/O请求的是()。
A.Select模型B.WSAAsyncSelect模型C.WSAEventSelect模型D.完成端口模型3.在ioctlsocket()函数中使用()参数,并将argp参数设置为非0值,可以将Socket设置为非阻塞模式。
A.FIONBIO B.FIONREADC.SIOCATMARK D.FIONONBLOCK4.在执行select()函数时如果出现错误则返回()。
A.0 B.−1C.NULL D.SOCKET_ERROR5.在WSAEventSelect模型中,调用WSAEventSelect()函数注册网络事件后,应用程序需要等待网络事件的发生,然后对网络事件进行处理。
Server.exe PortNumber,例如Server 8000 Client.exe IPAddress PortNumber,例如Client 127.0.0.1 8000 然后在客户端的命令⾏输⼊字符串并回车,客户端将会把消息发送到服务器,考试.⼤提⽰服务器再把消息传回客户端。
服务器端,Server.cpp //Server.cpp #include #include #include #pragma comment(lib,"ws2_32.lib") int main(int argc, char* argv[]){ //判断是否输⼊了端⼝号 if(argc!=2){ printf("Usage: %s PortNumber\n",argv[0]); exit(-1); } //把端⼝号转化成整数 short port; if((port = atoi(argv[1]))==0){ printf("端⼝号有误!"); exit(-1); } WSADATA wsa; //初始化套接字DLL if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){ printf("套接字初始化失败!"); exit(-1); } //创建套接字 SOCKET serverSocket; if((serverSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET){ printf("创建套接字失败!"); exit(-1); } struct sockaddr_in serverAddress; memset(&serverAddress,0,sizeof(sockaddr_in)); serverAddress.sin_family=AF_INET; serverAddress.sin_addr.S_un.S_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(port); //绑定 if(bind(serverSocket,(sockaddr*)&serverAddress,sizeof(serverAddress))==SOCKET_ERROR){ printf("套接字绑定到端⼝失败!端⼝: %d\n",port); exit(-1); } //进⼊侦听状态 if(listen(serverSocket,SOMAXCONN)==SOCKET_ERROR){ printf("侦听失败!"); exit(-1); } printf("Server %d is listening......\n",port); SOCKET clientSocket;//⽤来和客户端通信的套接字 struct sockaddr_in clientAddress;//⽤来和客户端通信的套接字地址 memset(&clientAddress,0,sizeof(clientAddress)); int addrlen = sizeof(clientAddress); //接受连接 if((clientSocket=accept(serverSocket,(sockaddr*)&clientAddress,&addrlen))==INVALID_SOCKET){ printf("接受客户端连接失败!"); exit(-1); } printf("Accept connection from %s\n",inet_ntoa(clientAddress.sin_addr)); char buf[4096]; while(1){ //接收数据 int bytes; if((bytes=recv(clientSocket,buf,sizeof(buf),0))==SOCKET_ERROR){ printf("接收数据失败!\n"); exit(-1); } buf[bytes]='\0'; printf("Message from %s: %s\n",inet_ntoa(clientAddress.sin_addr),buf); if(send(clientSocket,buf,bytes,0)==SOCKET_ERROR){ printf("发送数据失败!"); exit(-1); } } //清理套接字占⽤的资源 WSACleanup(); return 0; } 客户端,Client.cpp //Client.cpp #include #include #include #pragma comment(lib,"ws2_32.lib") int main(int argc, char* argv[]){ //判断是否输⼊了IP地址和端⼝号 if(argc!=3){ printf("Usage: %s IPAddress PortNumber\n",argv[0]); exit(-1); } //把字符串的IP地址转化为u_long unsigned long ip; if((ip=inet_addr(argv[1]))==INADDR_NONE){ printf("不合法的IP地址:%s",argv[1]); exit(-1); } //把端⼝号转化成整数 short port; if((port = atoi(argv[2]))==0){ printf("端⼝号有误!"); exit(-1); } printf("Connecting to %s:%d......\n",inet_ntoa(*(in_addr*)&ip),port); WSADATA wsa; //初始化套接字DLL if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){ printf("套接字初始化失败!"); exit(-1); } //创建套接字 SOCKET sock; if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET){ printf("创建套接字失败!"); exit(-1); } struct sockaddr_in serverAddress; memset(&serverAddress,0,sizeof(sockaddr_in)); serverAddress.sin_family=AF_INET; serverAddress.sin_addr.S_un.S_addr = ip; serverAddress.sin_port = htons(port); //建⽴和服务器的连接 if(connect(sock,(sockaddr*)&serverAddress,sizeof(serverAddress))==SOCKET_ERROR){ printf("建⽴连接失败!"); exit(-1); } char buf[4096]; while(1){ printf(">"); //从控制台读取⼀⾏数据 gets(buf); //发送给服务器 if(send(sock,buf,strlen(buf),0)==SOCKET_ERROR){ printf("发送数据失败!"); exit(-1); } int bytes; if((bytes=recv(sock,buf,sizeof(buf),0))==SOCKET_ERROR){ printf("接收数据失败!\n"); exit(-1); } buf[bytes]='\0'; printf("Message from %s: %s\n",inet_ntoa(serverAddress.sin_addr),buf); } //清理套接字占⽤的资源 WSACleanup(); return 0; }。
跨平台(Windows+Linux)的Socket通讯程序(一)—底层封装(转)【摘要】编写Socket通讯程序是一个老话题。
本文重点介绍Windows平台和Linux平台Socket通讯的不同,采用C++,编制了一个简单的跨平台的Socket通讯库。
一、Socket通讯的基础知识Socket通讯是两个计算机之间最基本的通讯方法,有TCP和UDP 两种协议。
关于这两种协议的区别,不少文章已有详述,这里,稍微总结一下:1.TCP是面向连接的,是“流”式的,意即通讯两端建立了一个“数码流管”,该流无头无尾,接收端保证接收顺序,但不保证包的分割。
2.UDP是面向无连接的,是“包”式的,意即通讯两端自由发送数据包,接收端不保证接收顺序,但保证包的分割与发送端一致。
正是基于上述二者的不同,在编程上,它们的区别如下:对TCP 连接,服务器端过程(bind->listen->accept->send/receive)与客户端不相同(connect->send/receive),对UDP连接,二者似乎更对等一些(服务器端仅需要bind)。
二、socket在windows下和linux下的区别一些文章也已涉及,这里,也是综合一下,并加上自己的理解。
三、跨平台的Socket辅助程序以下给出源代码。
sock_wrap.h代码如下,其中用到了platform.h,定义_WIN32_PLATFROM_和_LINUX_PLATFROM_两个宏。
[cpp]view plaincopy1.#ifndef _SOCK_WRAP_H_2.#define _SOCK_WRAP_H_3.4.#include "platform.h"5.6.#if defined(_WIN32_PLATFROM_)7.#include <winsock2.h>8.typedef SOCKET HSocket;9.#endif10.11.#if defined(_LINUX_PLATFORM_)12.#include <netinet/in.h>13.#include <sys/socket.h>14.#include <sys/types.h>15.16.typedef int HSocket;17.#define SOCKET_ERROR (-1)18.#define INVALID_SOCKET 019.#endif20.21.22.typedef struct23.{24.int block;25.int sendbuffersize;26.int recvbuffersize;27.int lingertimeout;28.int recvtimeout;29.int sendtimeout;30.} socketoption_t;31.32.typedef struct33.{34.int nbytes;35.int nresult;36.} transresult_t;37.38.int InitializeSocketEnvironment();39.void FreeSocketEnvironment();40.void GetAddressFrom(sockaddr_in *addr, const char *i p, int port);41.void GetIpAddress(char *ip, sockaddr_in *addr);42.bool IsValidSocketHandle(HSocket handle);43.int GetLastSocketError();44.45.HSocket SocketOpen(int tcpudp);46.void SocketClose(HSocket &handle);47.48.int SocketBlock(HSocket hs, bool bblock);49.int SocketTimeOut(HSocket hs, int recvtimeout, int sen dtimeout, int lingertimeout);50.51.int SocketBind(HSocket hs, sockaddr_in *addr);52.HSocket SocketAccept(HSocket hs, sockaddr_in *addr) ;53.int SocketListen(HSocket hs, int maxconn);54.55.void SocketSend(HSocket hs, const char *ptr, int nbyte s, transresult_t &rt);56.void SocketRecv(HSocket hs, char *ptr, int nbytes, tran sresult_t &rt);57.void SocketTryRecv(HSocket hs, char *ptr, int nbytes, i nt milliseconds, transresult_t &rt);58.void SocketTrySend(HSocket hs, const char *ptr, int nb ytes, int milliseconds, transresult_t &rt);59.60.void SocketClearRecvBuffer(HSocket hs);61.62.class CSockWrap63.{64.public:65.CSockWrap(int tcpudp);66.~CSockWrap();67.void SetAddress(const char *ip, int port);68.void SetAddress(sockaddr_in *addr);69.int SetTimeOut(int recvtimeout, int sendtimeout, int li ngertimeout);70.int SetBufferSize(int recvbuffersize, int sendbuffersize);71.int SetBlock(bool bblock);72.73.HSocket GetHandle () { return m_hSocket;}74.void Reopen(bool bForceClose);75.void Close();76.transresult_t Send(void *ptr, int nbytes);77.transresult_t Recv(void *ptr, int nbytes );78.transresult_t TrySend(void *ptr, int nbytes, int milliseco nds);79.transresult_t TryRecv(void *ptr, int nbytes, int milliseco nds );80.void ClearRecvBuffer();81.82.protected:83.HSocket m_hSocket;84.sockaddr_in m_stAddr;85.int m_tcpudp;86.};87.88.89.#endifsock_wrap.cpp代码如下,其中引用了lightThread.h和spantime.h,它们的代码见“跨平台(Windows+Linux)的线程辅助程序”。
实验七 Socket网络编程一、学时:4二、实验类型:设计性实验三、实验目的:1.熟悉VisualC++的基本操作。
2.基本了解基于对话框的windows应用程序的编写过程。
3.对于Windows Socket编程建立初步概念。
四、实验内容:利用Socket编写聊天程序。
五、实验原理:一、Windows Socket和套接口的基本概念套接口,就是一个指向传输提供者的句柄。
Win32中,套接口不同于文件描述符,所以它是一个独立的类型——SOCKET。
Windows Sockets描述定义了一个Microsoft Windows的网络编程界面,它是从Unix Socket 的基础上发展而来的,为Windows TCP/IP 提供了一个BSD型的套接字规范,除与Unix Sockets完全兼容外,还包括一个扩充文件,通过一组附加的 A PI实现Windows 式(即事件驱动)的编程风格;而Winsock则是在Microsoft Windows 中进行网络应用程序设计的接口。
Windows在Internet支配域中的TCP/IP协议定义了Winsock网络编程规范,融入了许多新特点。
使用Socket的目的是使用户在网络协议上工作而不必对该网络协议有非常深入的了解。
此外,编写的程序还可被迅速地移植到任何支持Socket的网络系统中去。
Winsock提供了一种可为指定传输协议打开、计算和关闭会话的能力。
在Windows下,TCP/IP上层模型在很大程度上与用户的Winsock应用有关;换言之,用户的Winsock应用控制了会话的方方面面,必要时,还会根据程序的需要格式化数据。
套接口有三种类型:流式套接口、数据报套接口及原始套接口。
流式套接口定义了一种可靠的面向连接的服务(利用TCP协议),实现了无差错无重复的顺序数据传输。
数据报套接口定义了一种无连接的服务(UDP 协议),数据通过相互独立的报文进行传输,是无序的,并且不保证可靠和无差错。
winsock编程实验报告Winsock编程实验报告引言:Winsock(Windows Socket)是一种用于网络通信的编程接口,常用于开发基于TCP/IP协议的应用程序。
本篇文章将介绍我对Winsock编程的实验经历和心得体会。
实验目的:通过Winsock编程实验,深入了解网络通信原理和技术,掌握基于TCP/IP协议的应用程序开发方法。
实验环境:本次实验在Windows操作系统下进行,使用了Visual Studio 2019作为开发工具。
实验过程:1. 实验一:建立基于TCP的客户端/服务器通信在这个实验中,我首先创建了一个服务器程序和一个客户端程序。
服务器程序使用Winsock库函数创建了一个套接字,并绑定到指定的IP地址和端口上。
客户端程序通过Winsock库函数创建了一个套接字,并连接到服务器的IP地址和端口上。
通过这个实验,我学会了如何建立基于TCP的客户端/服务器通信。
2. 实验二:实现基于UDP的数据传输在这个实验中,我创建了一个基于UDP的数据传输程序。
UDP是一种无连接的传输协议,相对于TCP来说,它更加轻量级,适用于一些对数据可靠性要求不高的应用场景。
通过这个实验,我学会了如何使用Winsock库函数实现基于UDP的数据传输。
3. 实验三:实现多线程服务器在这个实验中,我将服务器程序改为多线程模式。
通过创建多个线程,服务器可以同时处理多个客户端的请求,提高了系统的并发性能。
这个实验让我更加深入地理解了多线程编程和网络通信的结合。
实验结果与分析:通过以上实验,我成功地实现了基于TCP和UDP的网络通信,并且在实验三中实现了多线程服务器。
在实验过程中,我遇到了一些问题,比如套接字的创建和绑定、连接的建立和断开等。
但通过查阅文档和调试,我最终解决了这些问题。
实验结果表明,Winsock编程是一种强大且灵活的工具,可以满足各种网络通信需求。
实验心得:通过本次实验,我对Winsock编程有了更深入的了解。
一、实验目的1. 理解网络编程的基本原理和概念。
2. 掌握TCP/IP协议栈的基本工作原理。
3. 学习使用Socket编程实现网络通信。
4. 熟悉网络编程中的多线程编程技术。
5. 提高实际编程能力和问题解决能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 20194. 网络编程库:Winsock三、实验内容1. 网络编程基础2. Socket编程3. 多线程编程4. 客户端-服务器模式四、实验步骤1. 网络编程基础(1)了解网络编程的基本概念,如IP地址、端口号、协议等。
(2)学习TCP/IP协议栈的工作原理,包括OSI七层模型和TCP/IP四层模型。
2. Socket编程(1)学习Socket编程的基本原理,包括Socket创建、连接、发送、接收和关闭等操作。
(2)编写一个简单的TCP客户端程序,实现与服务器端的通信。
(3)编写一个简单的TCP服务器程序,接收客户端的连接请求,并实现数据交互。
3. 多线程编程(1)学习多线程编程的基本原理,了解线程、进程、并发和同步等概念。
(2)在客户端程序中添加多线程,实现同时与多个服务器进行通信。
(3)在服务器程序中添加多线程,实现同时处理多个客户端的连接请求。
4. 客户端-服务器模式(1)实现一个简单的文件传输客户端,实现文件的发送和接收。
(2)实现一个简单的文件传输服务器,接收客户端的文件传输请求,并完成文件传输。
五、实验结果与分析1. 网络编程基础通过学习网络编程基础,我们了解了网络编程的基本概念和TCP/IP协议栈的工作原理,为后续的Socket编程打下了基础。
2. Socket编程(1)通过编写TCP客户端程序,实现了与服务器端的通信,验证了Socket编程的基本原理。
(2)通过编写TCP服务器程序,接收客户端的连接请求,并实现了数据交互,进一步巩固了Socket编程的知识。
3. 多线程编程通过在客户端和服务器程序中添加多线程,实现了同时与多个服务器进行通信和同时处理多个客户端的连接请求,提高了程序的并发处理能力。
win32WinSock2⽹络编程socket-tcp通信今天复习了⼀下tcp通信的实现,写了写代码。
简单的总结⼀下:服务器作为监听者的⾓⾊需要先创建服务器socket套接字,然后使⽤bind绑定套接字和端⼝信息等等,再创建⽤于连接客户端的socket套接字,使⽤accept函数等待客户端的连接并处理。
客户端则只需要创建⽤于连接服务器的socket套接字connect函数建⽴与远程主机的链接就可以了。
同时需要注意的是错误的处理和关闭套接字等等。
服务器:1 #include<WinSock2.h>2#pragma comment(lib,"ws2_32.lib")3 #include <stdio.h>4 #include <string.h>5678int main(){9 WSADATA wsaData; // 初始化返回信息结构体10 WORD wVersion = MAKEWORD(2,2); // 制作版本号11 SOCKET hServer; // 定义套接字句柄12if (WSAStartup(wVersion, &wsaData)){ //初始化13 printf("initial failed");14return0;15 }16//in_addr addr; // ip地址结构体17//addr.s_addr = inet_addr("127.0.0.1"); // 转化字符串为32位整形ip地址18//char* lpszIp = inet_ntoa(addr); //整形转化为字符串形式1920 hServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //tcp形式流式套接字21if (hServer == INVALID_SOCKET){22 printf("socket failed \n");23 }24 sockaddr_in addrServer;25 addrServer.sin_family = AF_INET;26 addrServer.sin_port = htons(8888); // 指定端⼝27 addrServer.sin_addr.s_addr = htonl(INADDR_ANY); //指定能访问的ip28int nRet = bind(hServer, (sockaddr*)&addrServer, sizeof(addrServer));29if (nRet == SOCKET_ERROR){30 printf("bind error \n");31 closesocket(hServer);32 WSACleanup();33return0;34 }35//进⾏监听36 nRet = listen(hServer,5); //最多监听5个37 printf("start listening ... \n");38if (nRet == SOCKET_ERROR){39 printf("listen error \n");40 closesocket(hServer);41 WSACleanup();42return0;43 }4445//接收客户端请求46 SOCKET hClient;47 sockaddr_in addrClient;48int nLen = sizeof(addrClient);49 hClient = accept(hServer,(sockaddr *)&addrClient, &nLen); // ?建⽴监听句柄,直到接收到请求50if (hClient == INVALID_SOCKET){51 printf("accept error \n");52 closesocket(hServer);53 WSACleanup();54return0;55 }56 printf("Get a connect! \n");57 send(hClient, "helllllllooooooo",sizeof("helllllllooooooo"), 0);5859char szBuf[255];60//循环接收客户端数据61while (1)62 {63 memset(szBuf, 0, sizeof(szBuf)); // 清空缓冲区64 nRet = recv(hClient, szBuf,sizeof(szBuf),0);65if (nRet == SOCKET_ERROR){66 printf("recv error \n");67 closesocket(hClient);68 closesocket(hServer);69 WSACleanup();70return0;71 }7273char sPrint[sizeof(szBuf)];74 sprintf(sPrint, "IP:%s, recv msg: %s ",inet_ntoa(addrClient.sin_addr),szBuf);//格式化字符串75 printf(sPrint);76if(strcmp(szBuf, "close") == 0){ // 检测退出77 nRet = send(hClient,"close",strlen("close"), 0);78break;79 }80else{81//接收到数据82 sprintf(sPrint, "the server has recved your msg: %s ", szBuf);83 nRet = send(hClient,sPrint,strlen(sPrint), 0);84if (nRet == SOCKET_ERROR){85 printf("send err \n");86 closesocket(hClient);87 closesocket(hServer);88 WSACleanup();89return0;90 }91 }929394 }95 closesocket(hClient);96 closesocket(hServer);97 WSACleanup();9899return0;100 }客户端:1 #include<WinSock2.h>2#pragma comment(lib,"ws2_32.lib")3 #include <stdio.h>4 #include <string.h>5678int main(){9 WSADATA wsaData; // 初始化返回信息结构体10 WORD wVersion = MAKEWORD(2,2); // 制作版本号11 SOCKET hClient; // 定义套接字句柄12if (WSAStartup(wVersion, &wsaData)){ //初始化13 printf("initial failed");14return0;15 }1617 hClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //tcp形式流式套接字18if (hClient == INVALID_SOCKET){19 printf("socket failed \n");20 }2122 sockaddr_in addrServer;23 addrServer.sin_family = AF_INET;24 addrServer.sin_port = htons(8888); // 指定端⼝25 addrServer.sin_addr.s_addr = inet_addr("192.168.56.101"); //指定要连接的ip26//建⽴连接27int nRet = connect(hClient,(sockaddr*)&addrServer, sizeof(addrServer));28if (nRet == SOCKET_ERROR){29 printf("connect error \n");30 closesocket(hClient);31 WSACleanup();32return0;33 }34 printf("connect successsssss\n");3536char szBuf[255];37//循环接收客户端数据38while (1)39 {40 memset(szBuf, 0, sizeof(szBuf)); // 清空缓冲区41 nRet = recv(hClient, szBuf,sizeof(szBuf),0);42if (nRet == SOCKET_ERROR){43 printf("recv error \n");44 closesocket(hClient);45 WSACleanup();46return0;47 }4849char sPrint[sizeof(szBuf)];50 sprintf(sPrint, "recv msg: %s ",szBuf);//格式化字符串51 printf(sPrint);52if(strcmp(szBuf, "close") == 0){ // 检测退出53 nRet = send(hClient,"close",strlen("close"), 0);54break;55 }56else{57//接收到数据58if (strcmp(szBuf, "helllllllooooooo") == 0){59 send(hClient, "wow", sizeof("wow"),0);60 }61 }626364 }65 closesocket(hClient);66 WSACleanup();6768return0;69 }。
WindowsSocket接⼝简介 Windows Socket接⼝是Windows下⽹络编程的接⼝,在介绍Windows Socket接⼝之前,⾸先要简单介绍⼀下TCP/IP协议和描述⽹络系统架构的 OSI模型,以及TCP/IP模型。
⼀般来说,⽹络系统的架构可以⽤开放系统互联模型(OSI模型)来描述,OSI模型分层的思想类似于Windows等操作系统的分层,在Windows下,应⽤程序位于最⾼层,应⽤程序通过API调⽤位于中间层次的系统⼦程序,系统⼦程序再调⽤驱动程序,驱动程序最终操作计算机的硬件,各层次之间的隔离有利于层次间的分⼯协作,只要每个层次都严格遵守边界协定,那么它对于其他层次来说就可以看成是⼀个 “ ⿊匣⼦ “,结果就是开发⼈员能够致⼒于本层次的开发和提⾼,⽽不必担⼼能否和其他层次合作。
与之类似, OSI模型的体系结构分为7层,其中⽹络应⽤程序位于最⾼层,通过多个层次最终控制⽹络硬件所在的物理层来收发数据包。
TCP/IP是Transmission Control Protocol/Internet Protocol (传输控制协议/⽹际协议)的缩写,它最初是在20世纪70年代初期由美国国防部出资为ARPA(美国⾼级研究项⽬局)开发的,经过了多年以后,以TCP/IP 协议为基础构建的ARPA⽹逐步演变成了今天的 Internet。
TCP/IP⽹络的架构可以⽤TCP/IP模型来描述,这个模型和OSI模型极为相似,但是它将层次的划分减少到了4层,其每⼀层在功能上和OSI模型的⼀层或多层相对应,两种模型从⼯作原理上看并没有本质的区别。
图16.1描述了OSI模型和TCP/IP模型各层次之间的对应关系,并例举了部分在各层次上⼯作的⽹络协议,读者可以在其中看到很多熟悉的名词,如Telnet,HfTP,TCP和UDP等。
图16.l OSI模型、TCP/IP模型的结构和WinSock接⼝的关系 TCP/IP协议的核⼼协议运⾏于传输层和Internet层上,主要包括TCP, UDP和IP协议,其中TCP协议和UDP协议是以IP协议为基础⽽封装的,这两种协议提供了不同⽅式的数据通信服务。
实验名称实验二Windows Sockets编程基础训练【实验目的】了解Windows Sockets API的基本函数功能,掌握Windows Sockets的编程环境配置,掌握网络程序设计的基本过程。
【实验要求】1、使用Windows Sockets的API函数获得本机的IP地址。
2、使用Windows Sockets的API函数获得给定域名的IP地址。
【实验作业】使用WinSock 2.2实现网络通信的功能,则需要引用头文件winsock2.h和库文件ws2_32.lib,代码如下:#include<winsock2.h>#pragma comment(lib, "ws2_32.lib")MSDN中关于gethostbyname函数的说明gethostname(host_name, 128)Host_name修改后的值MSDN中关于gethostbyname函数的说明pHost = gethostbyname(host_name);pHost修改后的值MSDN中关于hostent结构的说明struct in_addr addr;memcpy(&addr, pHost->h_addr_list[i], sizeof(struct in_addr));Addr第一次修改后的值MSDN中关于in_addr结构的说明inet_ntoa(addr)MSDN中关于inet_ntoa()函数的说明程序运行截图gethostbyname()takes a string like “”, and returns a struct hostent which contains tons of information, including the IP address.——Beej’s Guide to Network Programming Using Internet Socketsprintf("Host name is:");scanf("%s",host_name);pHost = gethostbyname(host_name);域名解析后pHost中的内容程序运行截图以下是程序代码:#include"stdafx.h"#include"winsock2.h"#pragma comment( lib, "ws2_32" )int _tmain(int argc, _TCHAR* argv[]) {char host_name[128];struct hostent * pHost; //The hostent structure is used by functions to store information about a given host WSADATA wsaData; //WSADATA结构体包含了系统所支持的winsock版本信息if(WSAStartup(MAKEWORD(2,2), &wsaData )!=0) {printf("WSAStartup失败");return 0;}printf("Host name is:");scanf("%s",host_name);pHost = gethostbyname(host_name);struct in_addr addr;memcpy(&addr, pHost->h_addr_list[0], sizeof(struct in_addr));printf("\nAddress : %s" , inet_ntoa(addr));if(WSACleanup()==SOCKET_ERROR) {printf("WSACleanup失败");}return 0;}。
//server
#include<stdio.h>
#include<windows.h>
#include<winsock.h>
#define PORT 6600
int main() {
WSADATA ws;
SOCKET sockfd, clientfd;
int ret,addrlen;
struct sockaddr_in seraddr;
struct sockaddr_in cliaddr;
char buf[128];
ret = WSAStartup(MAKEWORD(2,2), &ws);
if (ret != 0) {
printf("Init Windows Socket Failed!\n");
return -1;
}
sockfd = socket(AF_INET,SOCK_STREAM,0);
if (sockfd == INV ALID_SOCKET) {
printf("Socket Create Failed!\n");
return -1;
}
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(PORT);
seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(sockfd,(struct sockaddr*)&seraddr,sizeof(seraddr)); if (ret == -1) {
printf("Socket Bind Failed!\n");
closesocket(sockfd);
return -1;
}
ret = listen(sockfd,5);
if (ret == -1) {
printf("Sockfd Listen Failed!\n");
closesocket(sockfd);
return -1;
}
printf("Socket Listening...\n");
addrlen = sizeof(cliaddr);
while(1) {
clientfd = accept(sockfd,(struct sockaddr*)&cliaddr,&addrlen);
if (clientfd == INV ALID_SOCKET) {
printf("Sockfd Accept Failed!\n");
closesocket(sockfd);
return -1;
}
while(1) {
memset(buf,0,sizeof(buf));
ret = recv(clientfd,buf,sizeof(buf),0);
if (ret == -1){
printf("Socket Receive Failed!\n");
closesocket(clientfd);
}
return 0;
}
//client
#include<stdio.h>
#include<windows.h>
#include<winsock.h>
#define PORT 6600
#define SERIP "10.167.12.108"
int main() {
WSADATA ws;
SOCKET sockfd;
int ret;
struct sockaddr_in seraddr;
char buf[128];
ret = WSAStartup(MAKEWORD(2,2), &ws);
if (ret != 0) {
printf("Init Windows Socket Failed!\n");
return -1;
}
sockfd = socket(AF_INET,SOCK_STREAM,0);
if (sockfd == INV ALID_SOCKET) {
printf("Socket Create Failed!\n");
return -1;
}
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(PORT);
seraddr.sin_addr.s_addr = inet_addr(SERIP);
ret = connect(sockfd,(struct sockaddr*)&seraddr,sizeof(seraddr)); if (ret == -1) {
printf("Socket Connect Failed!\n");
closesocket(sockfd);
return -1;
}
while(1) {
memset(buf,0,sizeof(buf));
scanf("%s",buf);
ret = send(sockfd,buf,strlen(buf),0);
if (ret == -1){
printf("Socket Send Failed!\n");
closesocket(sockfd);
}
}
return 0;
}。