windows下的socket网络编程
已经很久没有在windows下编程了,这次因为需要做一个跨平台的网络程序,就先写了个简单的winSocket
网路通信的例子,以便以后用到的时候有个参考。
windows下使用winsock
编程与linux/unix
的区别在于windows下需要先有一个初始化
的操作,结束的时候需要一个清理
的操作。还有windows下编译的时候需要连接ws32_lib
库。
大致过程如下
-
1、初始化
/*加载Winsock DLL*/
WSADATA wsd;
if (WSAStartup(MAKEWORD(2 , 2) , &wsd) != 0) {
printf("Winsock 初始化失败! ");
return 1;
}
-
2、socket相关函数调用
socket(...)
bind(...)
listen(...)
connect(...)
accept(...)
send/sendto
recv/recvfrom
-
3、清理
WSACleanup();
clinet.c 客户端
客户端的流程很简单。
- 1、先是使用
socket
函数产生一个打开的socket
文件描述符。 - 2、使用
connect
函数去连接服务端 - 3、使用
read/recv
等读文件函数从服务端接收数据,使用write/send
等写文件的函数向服务端发送数据
上面是典型的TCP
编程流程,如果是UDP
的话不需要connect
去连接服务端直接使用sendto
函数来发送数据,使用recvfrom接收来自服务器的数据
server.c 服务器端
服务器端的流程比客户端稍微复杂一点
- 1、调用
socket
打开一个socket句柄 - 2、调用
bind
来绑定socket句柄到一个网口的某个端口 - 3、调用
listen
来设置(启用)监听 - 4、调用
accept
来等待客户端的连接
上面是典型的TCP
编程流程,如果是UDP
的,那么不需要3,4
这两部,直接使用recvfrom
来接收客户端发过来的数据即可。
UDP通信的实现
我这里没有写TCP
的,因为都是局域网内,就简单的写了个。
这里是在虚拟机里面测试的截图,代码见最后。
代码如下
这是TCP的,UDP的就不贴了。
#include <winsock2.h> #include <stdio.h> #include <stdlib.h> #pragma comment(lib , "ws2_32.lib") #define BUFSIZE 4096 /*缓冲区大小*/ int main_client(int argc , char *argv[]) { WSADATA wsd; SOCKET sClient; char Buffer[BUFSIZE]; int ret; struct sockaddr_in server; unsigned short port; struct hostent *host = NULL; if (argc < 3) { printf("Usage:%s IP Port " , argv[0]); return -1; } /*加载Winsock DLL*/ if (WSAStartup(MAKEWORD(2 , 2) , &wsd) != 0) { printf("Winsock 初始化失败! "); return 1; } /*创建Socket*/ sClient = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP); if (sClient == INVALID_SOCKET) { printf("socket() 失败: %d " , WSAGetLastError()); return 1; } /*指定服务器地址*/ server.sin_family = AF_INET; port = atoi(argv[2]); server.sin_port = htons(port); server.sin_addr.s_addr = inet_addr(argv[1]); if (server.sin_addr.s_addr == INADDR_NONE) { host = gethostbyname(argv[1]); //输入的地址可能是域名等 if (host == NULL) { printf("无法解析服务端地址: %s " , argv[1]); return 1; } CopyMemory(&server.sin_addr , host->h_addr_list[0] , host->h_length); } /*与服务器建立连接*/ if (connect(sClient , (struct sockaddr*)&server , sizeof(server)) == SOCKET_ERROR) { printf("connect() 失败: %d " , WSAGetLastError()); return 1; } /*发送、接收消息*/ for (;;) { //从标准输入读取要发送的数据 //gets_s(Buffer,BUFSIZE); gets(Buffer); //向服务器发送消息 ret = send(sClient , Buffer , strlen(Buffer) , 0); if (ret == 0) { break; } else if (ret == SOCKET_ERROR) { printf("send() 失败: %d " , WSAGetLastError()); break; } printf("Send %d bytes " , ret); //接收从服务器来的消息 ret = recv(sClient , Buffer , BUFSIZE , 0); if (ret == 0) { break; } else if (ret == SOCKET_ERROR) { printf("recv() 失败: %d " , WSAGetLastError()); break; } Buffer[ret] = '