vc++深入详解之第十四章网络编程笔记

由于不同的计算机存放数据字节的顺序不同,这样发送方发送数据后,即使接收方接收到该数据,也有可能无法查看所接收到的数据。所以在网络中不同主机间进行通信时,要统一采用网络字节顺序。 客户机/服务器模式在操作过程中采取的是主动请求的方式。首先服务器方要先启动,并根据请求提供相应的服务: ①打开一个通信信道并告知本地主机,它愿意在某一地址和端口接收客户请求。 ②等待客户请求到达端口。 ③接收到重复服务请求,处理该请求并发送应答信号。接收到并发服务器请求,要激活一个新的进程来处理这个客户请求。新进程处理此客户请求,并不需要对其他请求作出应答。服务完成以后,关闭此新进程与可与的通信链路,并终止。 ④返回第二步,等待另一客户请求 ⑤关闭服务器。 而客户方: ①打开一个通信信道,并连接到服务器所在主机的特定端口。 ②向服务器发送服务请求报文,等待并接收应答;继续提出请求。 ③请求结束后关闭通信通道并终止。 套接字的类型: 流式套接字(SOCK_STREAM——IP) 数据报式套接字(SOCK_DGRAM——TCP) 原始套接字(SOCK_RAW) 基于TCP的socket编程: 服务器端: ①创建套接字(socket) ②将套接字绑定到一个本地地址和端口上(bind) ③将套接字设为监听模式,准备接收客户端请求(listen) ④等待客户请求到来;当请求到来后,接收连接请求,返回一个新的对应于此连接的套接字(accept) ⑤用返回的套接字和客户端进行通信(send/recv) ⑥返回,等待另一客户请求 ⑦关闭套接字 客户端: ①创建套接字(socket ②向服务器发出连接请求(connect) ③和服务器端进行通信(send/recv) ④关闭套接字 基于UDP的socket编程 服务器端: ①创建套接字(socket) ②将套接字绑定到一个本地地址和端口上(bind) ③等待接收数据(recvfrom) ④关闭套接字 客户端: ①创建套接字(socket) ②向服务器发送数据(sendto) ③关闭套接字 加载套接字字库WSAStartup、WSAClearUp socket函数: SOCKET socket( int af , int type, int protocol);如果调用成功则返回一个新的SOCKET数据类型的套接字描述符;如果调用失败,这个函数就会返回一个INVALID_SOCKET值,错误信息可以通过WSAGetLastError函数返回。 bind函数: int bind( SOCKET s, const struct sockaddr FAR* name, int namelen); inet_addr和inet_ntoa函数: inet_addr函数将点分十进制转换为一个合适分配给S_addr的u_long类型的数值,inet_ntoa函数完成相反的工作。 int listen( SOCKET s, int backlog); SOCKET accpet( SOCKET s, struct sockaddr *addr, int addrlen); int send(SOCKET s, const char buf, int len , int flags); int recv(SOCKET s, char *buf , int len , int flags); int connect(SOCKET s, const struct sockaddr *name, int namelen); int recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr*from , int fromlen); int sendto(SOCKET s, const char *buf, int len, int flags, const struct sockadd *to, int tolen); htons和htonl函数: Window Sockets的htons函数将把一个u_short类型的值从主机字节顺序转换为TCP/IP网络字节顺序。htonl把一个u_long类型的值从主机字节顺序转换为TCP/IP网络字节顺序。 基于TCP的服务器端: #include <Winsock2.h> #include<stdio.h> #include <string.h> void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); 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); 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( true ) { SOCKET sockConn = accept( sockSrv , (SOCKADDR*)&addrClient, &len); char sendBuf[100]; sprintf( sendBuf , "Welcome %s to http://www.sunxin.org", inet_ntoa(addrClient.sin_addr)); send( sockConn, sendBuf, strlen(sendBuf) + 1, 0); char recvBuf[100]; recv( sockConn, recvBuf, 100, 0); printf("%s\n", recvBuf); } } 基于TCP的客户机端: #include <Winsock2.h> #include<stdio.h> #include <string.h> void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1); 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"); 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 lalor", strlen("This is lalor") + 1, 0); closesocket(sockClient); WSACleanup(); return; } 基于UDP的服务器端: #include<winsock2.h> #include<stdio.h> void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1); 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_DGRAM, 0); 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)); 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( strcmp( "exit" , recvBuf) == 0 ) { sendto( sockSrv, "exit", strlen("exit") + 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); printf("Please input data:\n"); gets(sendBuf); sendto(sockSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR*)&addrClient, len); } closesocket(sockSrv); WSACleanup(); } 基于UDP的客户端: #include<winsock2.h> #include<stdio.h> void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1); 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_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); char recvBuf[100]; char sendBuf[100]; char tempBuf[100]; 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( strcmp("exit" , recvBuf) == 0 ) { sendto(sockClient, "exit" , strlen("exit" + 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(); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值