A Simple Socket Application

来源:互联网 发布:网络链路测试工具 编辑:程序博客网 时间:2024/05/16 08:02

因为我的毕业设计要用到网络,一开始我就打算做 IOCP Server,我想用最好的方法去实现,结果发现啃不动,于是就从这个示例程序开始吧!

客户端代码:

/* * 文件:简单示例(客户端) * 说明:项目中需包含 Ws2_32.lib,或使用 #pragma once */#include <stdio.h>#include <WinSock2.h>#define LENGTH 128#define PORT_NUM 8086#define EXIT_WITH_MESSAGE(content) \do \{ \WSACleanup(); \printf_s(content); \system("pause"); \return EXIT_FAILURE; \} \while (FALSE);int main(){int ret, len;WORD wVersion;// 网络传输版本WSADATA wsaData;// WSADATAchar msg[LENGTH];struct sockaddr_in server;// 服务器信息SOCKET sockClient = INVALID_SOCKET;// 待创建的套接字wVersion = MAKEWORD(2, 2);ret = WSAStartup(wVersion, &wsaData);// 初始化 WinSock DLLif (ret != 0){// 告诉用户不能获取可用的 WinSock DLLEXIT_WITH_MESSAGE("WSAStartup Failed, cannot find a usable winsock dll!\n");}if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){// 告诉用户版本不正确EXIT_WITH_MESSAGE("Error version!\n");}sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (INVALID_SOCKET == sockClient){// 套接字创建失败EXIT_WITH_MESSAGE("Invalid socket!\n");}server.sin_family = AF_INET;server.sin_port = htons(PORT_NUM);server.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");ret = connect(sockClient, (struct sockaddr *)&server, sizeof(struct sockaddr));if (SOCKET_ERROR == ret){// 连接失败closesocket(sockClient);EXIT_WITH_MESSAGE("Connect failed!\n");}do{printf_s("Input a message to send (Note: Length < 128): ");gets_s(msg, LENGTH);// send 函数将会把消息发送到已连接的套接字上,而 sendto 则是发送到指定套接字上len = strlen(msg) + 1;ret = send(sockClient, msg, len, 0);if (ret < 0 || ret > len){// 发送有误closesocket(sockClient);EXIT_WITH_MESSAGE("Send message error!\n");}if (strcmp(msg, "Quit") == 0)break;memset(msg, 0, LENGTH);ret = recv(sockClient, msg, LENGTH, 0);if (SOCKET_ERROR == ret){// 接受有误closesocket(sockClient);EXIT_WITH_MESSAGE("Receive message error!\n");}else if (0 == ret){// 连接断开closesocket(sockClient);EXIT_WITH_MESSAGE("The connection closed!\n");}printf_s("Client reply: %s\n", msg);}while (strcmp(msg, "Quit"));printf_s("Exit connection!\n");closesocket(sockClient);WSACleanup();system("pause");return EXIT_SUCCESS;}


 

服务器端代码:

/* * 文件:简单示例(服务器端) * 说明:项目中需包含 Ws2_32.lib,或使用 #pragma once */#include <stdio.h>#include <WinSock2.h>#define LENGTH 128#define PORT_NUM 8086#define EXIT_WITH_MESSAGE(content) \do \{ \WSACleanup(); \printf_s(content); \system("pause"); \return EXIT_FAILURE; \} \while (FALSE);int main(){int ret, len;WORD wVersion;// 网络传输版本WSADATA wsaData;// WSADATAchar msg[LENGTH];struct sockaddr_in server, client;// 服务器信息,客户端信息SOCKET sockServer = INVALID_SOCKET, sockListener = INVALID_SOCKET;// 服务器套接字,监听套接字wVersion = MAKEWORD(2, 2);ret = WSAStartup(wVersion, &wsaData);// 初始化 WinSock DLLif (ret != 0){// 告诉用户不能获取可用的 WinSock DLLEXIT_WITH_MESSAGE("WSAStartup Failed, cannot find a usable winsock dll!\n");}if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){// 告诉用户版本不正确EXIT_WITH_MESSAGE("Error version!\n");}sockListener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (INVALID_SOCKET == sockListener){// 套接字创建失败EXIT_WITH_MESSAGE("Invalid listener socket!\n");}server.sin_family = AF_INET;server.sin_addr.s_addr = INADDR_ANY;server.sin_port = htons(PORT_NUM);ret = bind(sockListener, (struct sockaddr *)&server, sizeof(struct sockaddr_in));if (SOCKET_ERROR == ret){// 绑定端口失败closesocket(sockListener);EXIT_WITH_MESSAGE("Bind error!\n");}ret = listen(sockListener, SOMAXCONN);if (SOCKET_ERROR == ret){// 监听失败closesocket(sockListener);EXIT_WITH_MESSAGE("Listen error!\n");}len = sizeof(struct sockaddr_in);sockServer = accept(sockListener, (struct sockaddr*)&client, &len);if (INVALID_SOCKET == sockServer){// 接收失败closesocket(sockListener);EXIT_WITH_MESSAGE("Accept error!\n");}do{memset(msg, 0, LENGTH);ret = recv(sockServer, msg, LENGTH, 0);if (SOCKET_ERROR == ret){// 接受有误closesocket(sockServer);EXIT_WITH_MESSAGE("Receive message error!\n");}else if (0 == ret){// 连接断开closesocket(sockServer);EXIT_WITH_MESSAGE("The connection closed!\n");}printf_s("Client: %s\n", msg);strcpy_s(msg, LENGTH, "SweetLover has received your letter, he'll reply soon!");len = strlen(msg) + 1;ret = send(sockServer, msg, len, 0);if (ret <= 0 || ret > len){// 发送有误closesocket(sockServer);EXIT_WITH_MESSAGE("Send message error!\n");}}while (TRUE);printf_s("Exit connection!\n");closesocket(sockServer);closesocket(sockListener);WSACleanup();system("pause");return EXIT_SUCCESS;}


总结:

1.网络连接的步骤:http://blog.csdn.net/wwqingyue/article/details/8792608

UDP和TCP编程步骤也有些不同,如下: 

  TCP编程的服务器端一般步骤是: 

  1、创建一个socket,用函数socket();  2、设置socket属性,用函数setsockopt(); * 可选  3、绑定IP地址、端口等信息到socket上,用函数bind();  4、开启监听,用函数listen();  5、接收客户端上来的连接,用函数accept();  6、收发数据,用函数send()和recv(),或者read()和write();  7、关闭网络连接;  8、关闭监听;

 

  TCP编程的客户端一般步骤是: 

  1、创建一个socket,用函数socket();  2、设置socket属性,用函数setsockopt();* 可选  3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选  4、设置要连接的对方的IP地址和端口等属性;  5、连接服务器,用函数connect();  6、收发数据,用函数send()和recv(),或者read()和write();  7、关闭网络连接;

 

  与之对应的UDP编程步骤要简单许多,分别如下: 

  UDP编程的服务器端一般步骤是: 

  1、创建一个socket,用函数socket();  2、设置socket属性,用函数setsockopt();* 可选  3、绑定IP地址、端口等信息到socket上,用函数bind();  4、循环接收数据,用函数recvfrom();  5、关闭网络连接;

 

  UDP编程的客户端一般步骤是: 

  1、创建一个socket,用函数socket();  2、设置socket属性,用函数setsockopt();* 可选  3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选  4、设置对方的IP地址和端口等属性;  5、发送数据,用函数sendto();  6、关闭网络连接;

2.套接字编程原理:http://www.cnblogs.com/haoyuanyuan/p/3268351.html

3.常用术语概念:http://www.vckbase.com/index.php/wv/300

socket 通信关于bind那点事

 

0 0
原创粉丝点击