winsocket入门学习

来源:互联网 发布:免费搜狐会员软件 编辑:程序博客网 时间:2024/06/05 07:19

参考资料:http://c.biancheng.net/cpp/socket/

http://www.winsocketdotnetworkprogramming.com/


socket 是“套接字”意思,是计算机之间进行通信的一种约定。

通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。

学习 socket,也就是学习计算机之间如何通信,并编写出实用的程序。




WD--返回WinSock的实现信息。

WD是一个WSAData结构:

typedef struct WSAData {        WORD                    wVersion;        WORD                    wHighVersion;#ifdef _WIN64        unsigned short          iMaxSockets;        unsigned short          iMaxUdpDg;        char FAR *              lpVendorInfo;        char                    szDescription[WSADESCRIPTION_LEN+1];        char                    szSystemStatus[WSASYS_STATUS_LEN+1];#else        char                    szDescription[WSADESCRIPTION_LEN+1];        char                    szSystemStatus[WSASYS_STATUS_LEN+1];        unsigned short          iMaxSockets;        unsigned short          iMaxUdpDg;        char FAR *              lpVendorInfo;#endif} WSADATA, FAR * LPWSADATA;



最简单的WinSocket程序

server.c

#define _WINSOCK_DEPRECATED_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#pragma comment(lib, "ws2_32.lib")#define BUFFER_SIZE 1024int main(){WSADATAwsaData;//包含系统所支持的WinSocket版本信息SOCKETsServer;//服务器Socket,用于监听客户端请求SOCKETsClient;//客户端Socket,用于实现与客户端的通信intretVal;//调用各种Socket函数的返回值charbuf[BUFFER_SIZE];//用于接受客户端数据的缓冲区//初始化WinSocket 2.2if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){printf("WSAStartup failed!\n");return -1;}/***  打印socket信息*  低位字节存储主版本号,高位字节存储副版本号*/printf("[wVersion] = %d.%d\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));printf("[wHighVersion] = %d.%d\n", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));printf("[szDescription] = %s\n", wsaData.szDescription);printf("[szSystemStatus] = %s\n", wsaData.szSystemStatus);printf("[iMaxSockets] = %d\n", wsaData.iMaxSockets);printf("[iMaxUdpDg] = %d\n", wsaData.iMaxUdpDg);//创建用于监听的socketsServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sServer == INVALID_SOCKET){printf("socket failed!\n");WSACleanup();return -1;}/***  设置服务器socket地址*  服务器监听地址为INADDR_ANY-->在任意本地地址(0.0.0.0)监听*  监听端口号为9999*/SOCKADDR_IN addrServ;addrServ.sin_family = AF_INET;addrServ.sin_port = htons(9999);addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//绑定Sockets Server到本地地址retVal = bind(sServer, (const struct sockaddr*)&addrServ, sizeof(SOCKADDR_IN));if (retVal == SOCKET_ERROR){printf("bind failed!\n");closesocket(sServer);WSACleanup();return -1;}//在Sockets Server上进行监听retVal = listen(sServer, 1);if (retVal == SOCKET_ERROR){printf("listen failed!\n");closesocket(sServer);WSACleanup();return -1;}//接受来自客户端的请求printf("TCP Server start...\n");struct sockaddr_in addrClient;int addrClientlen = sizeof(addrClient);sClient = accept(sServer, (struct sockaddr FAR *)&addrClient, &addrClientlen);if (sClient == INVALID_SOCKET){printf("accept failed!\n");closesocket(sServer);WSACleanup();return -1;}//printf("%s\n", inet_ntoa(addrClient.sin_addr));while (1){//清空接收数据的缓冲区memset(buf, 0, sizeof(buf));retVal = recv(sClient, buf, BUFFER_SIZE, 0);if (retVal == SOCKET_ERROR){printf("recv failed\n");closesocket(sServer);closesocket(sClient);WSACleanup();return -1;}SYSTEMTIME st;GetLocalTime(&st);char szDateTime[50];sprintf(szDateTime, "%4d-%02d-%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay,st.wHour, st.wMinute, st.wSecond);//打印输出信息printf("%s, Recv From Client [%s:%d] :%s\n", szDateTime, inet_ntoa(addrClient.sin_addr), addrClient.sin_port, buf);if (strcmp(buf, "quit") == 0){send(sClient, "quit", strlen("quit"), 0);break;}else{char msg[BUFFER_SIZE];sprintf(msg, "Message received - %s", buf);retVal = send(sClient, msg, strlen(msg), 0);if (retVal == SOCKET_ERROR){printf("send failed\n");closesocket(sServer);closesocket(sClient);WSACleanup();return -1;}}}//清除工作closesocket(sServer);closesocket(sClient);WSACleanup();return 0;}
client.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#pragma comment(lib, "ws2_32.lib")#define BUFFER_SIZE 1024int main(){WSADATAwsaData;SOCKETsHost;intretVal;charbuf[BUFFER_SIZE];if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){printf("WSAStartup failed!\n");return -1;}sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sHost == INVALID_SOCKET){printf("socket failed!\n");WSACleanup();return -1;}SOCKADDR_IN addrServ;addrServ.sin_family = AF_INET;addrServ.sin_port = htons(9999);addrServ.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");retVal = connect(sHost, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));if (retVal == SOCKET_ERROR){printf("connect failed!\n");closesocket(sHost);WSACleanup();return -1;}while (1){printf("Please input a string:");gets(buf);retVal = send(sHost, buf, strlen(buf), 0);if (retVal == SOCKET_ERROR){printf("send failed!\n");closesocket(sHost);WSACleanup();return -1;}memset(buf, 0, sizeof(buf));retVal = recv(sHost, buf, sizeof(buf), 0);if (retVal == SOCKET_ERROR){printf("recv failed!\n");closesocket(sHost);WSACleanup();return -1;}printf("Recv From Server: %s\n", buf);if(strcmp(buf, "quit") == 0){break;}}//วๅณนคื๗closesocket(sHost);WSACleanup();return 0;}

对于完成的client/server程序可以使用NC来测试

1)连接到 remote 主机,例子:
格式:nc -nvv 192.168.x.x 80
讲解:连到192.168.x.x的TCP80端口

2)监听 local 主机,例子:
格式:nc -l -p 80
讲解:监听本机的TCP80端口



0 0
原创粉丝点击