windows下的socket网络编程
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 初始化失败!\n");
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 < ) {
printf("Usage:%s IP Port\n" , argv[]);
return -;
} /*加载Winsock DLL*/
if (WSAStartup(MAKEWORD( , ) , &wsd) != ) {
printf("Winsock 初始化失败!\n");
return ;
} /*创建Socket*/
sClient = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
if (sClient == INVALID_SOCKET) {
printf("socket() 失败: %d\n" , WSAGetLastError());
return ;
}
/*指定服务器地址*/
server.sin_family = AF_INET;
port = atoi(argv[]);
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(argv[]); if (server.sin_addr.s_addr == INADDR_NONE) {
host = gethostbyname(argv[]); //输入的地址可能是域名等
if (host == NULL) {
printf("无法解析服务端地址: %s\n" , argv[]);
return ;
}
CopyMemory(&server.sin_addr ,
host->h_addr_list[] ,
host->h_length);
}
/*与服务器建立连接*/
if (connect(sClient , (struct sockaddr*)&server ,
sizeof(server)) == SOCKET_ERROR) {
printf("connect() 失败: %d\n" , WSAGetLastError());
return ;
} /*发送、接收消息*/ for (;;) {
//从标准输入读取要发送的数据
//gets_s(Buffer,BUFSIZE);
gets(Buffer);
//向服务器发送消息
ret = send(sClient , Buffer , strlen(Buffer) , );
if (ret == ) {
break;
}
else if (ret == SOCKET_ERROR) {
printf("send() 失败: %d\n" , WSAGetLastError());
break;
}
printf("Send %d bytes\n" , ret);
//接收从服务器来的消息
ret = recv(sClient , Buffer , BUFSIZE , );
if (ret == ) {
break;
}
else if (ret == SOCKET_ERROR) {
printf("recv() 失败: %d\n" , WSAGetLastError());
break;
}
Buffer[ret] = '\0';
printf("Recv %d bytes:\n\t%s\n" , ret , Buffer); }
//用完了,关闭socket句柄(文件描述符)
closesocket(sClient);
WSACleanup(); //清理
return ;
}
查看 clinet.c 代码
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h> #pragma comment(lib , "ws2_32.lib") #define DEFAULT_BUFFER 4096 /*缓冲区大小*/ /*与客户机通信的线程函数*/
DWORD WINAPI ClientThread(LPVOID lpParam)
{
SOCKET sock = (SOCKET)lpParam;
char Buffer[DEFAULT_BUFFER];
int ret , nLeft , idx;
while () {
/*接收来自客户机的消息*/
ret = recv(sock , Buffer , DEFAULT_BUFFER , );
if (ret == )
break;
else if (ret == SOCKET_ERROR) {
printf("recv() 失败: %d\n" , WSAGetLastError());
break;
}
Buffer[ret] = '\0';
printf("Recv: %s\n" , Buffer); //打印接收到的消息 nLeft = ret;
idx = ;
while (nLeft > ) {
/*向客户机发送回应消息*/
ret = send(sock , &Buffer[idx] , nLeft , );
if (ret == )
break;
else if (ret == SOCKET_ERROR) {
printf("send() 失败: %d\n" , WSAGetLastError());
break;
}
nLeft -= ret;
idx += ret;
}
}
return ;
} int main_server(int argc , char **argv)
{
WSADATA wsd;
HANDLE hThread;
DWORD dwThread;
SOCKET sListen , sClient;
int AddrSize;
unsigned short port;
struct sockaddr_in local , client; if (argc < ) {
printf("Usage:%s Port\n" , argv[]);
return -;
} /*加载Winsock DLL*/
if (WSAStartup(MAKEWORD( , ) , &wsd) != ) {
printf("WinSock 初始化失败!\n");
return ;
} /*创建Socket*/
sListen = socket(AF_INET , SOCK_STREAM , IPPROTO_IP);
if (sListen == SOCKET_ERROR) {
printf("socket() 失败: %d\n" , WSAGetLastError());
return ;
} local.sin_family = AF_INET;
local.sin_addr.s_addr = htonl(INADDR_ANY);
port = atoi(argv[]); //获取端口值
local.sin_port = htons(port); /*绑定Socket*/
if (bind(sListen ,
(struct sockaddr*)&local ,
sizeof(local)) == SOCKET_ERROR) {
printf("bind() 失败: %d\n" , WSAGetLastError());
return ;
}
/*打开监听*/
listen(sListen , ); /*在端口进行监听,一旦有客户机发起连接请示
就建立与客户机进行通信的线程*/
while () {
AddrSize = sizeof(client);
/*监听是否有连接请求*/
sClient = accept(sListen ,
(struct sockaddr*)&client ,
&AddrSize);
if (sClient == INVALID_SOCKET) {
printf("accept() 失败: %d\n" , WSAGetLastError());
break;
}
printf("接受客户端连接: %s:%d\n" ,
inet_ntoa(client.sin_addr) ,
ntohs(client.sin_port)); //创建一个线程去处理
hThread = CreateThread(NULL , , ClientThread ,
(LPVOID)sClient , , &dwThread); if (hThread == NULL) {
printf("CreateThread() 失败: %d\n" , GetLastError());
break;
}
//处理完后关闭
CloseHandle(hThread);
}
closesocket(sListen);
WSACleanup(); //用完了要清理
return ;
}
查看 server.c 代码
测试代码(main)
extern int main_client(int , char**);
extern int main_server(int , char**); int main(int c , char** v)
{
if (c == ) {
main_client(c , v);
}
else {
main_server(c , v);
}
return ; }
查看 test 代码
windows下的socket网络编程的更多相关文章
- windows下的socket网络编程(入门级)
windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了,这次因为需要做一个跨平台的网络程序,就先 ...
- Cfree clion windows c语言 socket 网络编程
server.c #include <stdio.h> #include <winsock2.h> #define SERVER_PORT 5208 //侦听端口 int ma ...
- winsock教程- windows下的socket编程(c语言实现)
winsock教程- windows下的socket编程(c语言实现) 使用winsock进行socket 编程 这是一个学习windows下socket编程(c语言)的快速指南.这是因为一下 ...
- windows socket网络编程基础知识
下面介绍网络7层协议在WINDOWS的实现: 7层协议 WIN系统 ________________________________________ 7 应用层 7 应用程序 ____________ ...
- windows socket 网络编程
样例代码就在我的博客中,包含六个UDP和TCP发送接受的cpp文件,一个基于MFC的局域网聊天小工具project,和此小工具的全部执行时库.资源和执行程序.代码的压缩包位置是http://www.b ...
- linux下C语言socket网络编程简例
原创文章,转载请注明转载字样和出处,谢谢! 这里给出在linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到client的连接后,发送数据给client:clie ...
- 5.3linux下C语言socket网络编程简例
原创文章,转载请注明转载字样和出处,谢谢! 这里给出在Linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到客户端的连接后,发送数据给客户端:客户端在接受到数据后 ...
- 项目总结——深入浅出socket网络编程
前言: 为什么会有如题的概念呢,我想对于没有主动听说过socket网络编程的人来说读到题目可能就已经蒙头了,为了很好的让大家进入场景,首先说一下一个需要用到这点东西的业务需求. 首先大家应该明确的是s ...
- Socket网络编程详解
一,socket的起源 socket一词的起源 在组网领域的首次使用是在1970年2月12日发布的文献IETF RFC33中发现的, 撰写者为Stephen Carr.Steve Crocker和Vi ...
随机推荐
- Java递归算法——阶乘
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
- 最近这么火的iOS视频直播
快速集成iOS基于RTMP的视频推流 http://www.jianshu.com/p/8ea016b2720e iOS视频直播初窥:高仿<喵播APP> http://www.jiansh ...
- python openpyxl 操作 excel
初识与安装 Openpyxl is a Python library for reading and writing Excel 2010 xlsx/xlsm/xltx/xltm files. 安装 ...
- Robot Framework--10 万能的evaluate
转自:http://blog.csdn.net/tulituqi/article/details/10124559 这一讲我们重点来介绍一下一个常用的关键字evaluate. 我觉得这个关键字在RF里 ...
- 页面多次调用查询文章(have_posts())
通常来说一个页面只调用查询一次文章.have_posts() 如果页面,比如首页需要按照不同的查询参数调用多次文章 需要做如下处理: //loop前 $temp_query = $wp_que ...
- div+css使多行文字垂直居中?
1.单行文字: 设置height = line-height; 多行文字: 设置 padding, 自己要计算一下? vertical-align: 可以设置垂直居中, 但是只是针对本身就具有 ali ...
- 《C++编程规范》
1.使用编译器的最高警告级别,成功的构建应该是无声无息的(没有警告的). 如果确定是无害警告,且是无法修改的第三方头文件引起的,可以用自己的头文件包装起来,并有选择性的关闭警告,然后项目中使用该头文件 ...
- HTML中head头结构
HTML head 头部分的标签.元素有很多,涉及到浏览器对网页的渲染,SEO等等,而各个浏览器内核以及各个国内浏览器厂商都有些自己的标签元素,这就造成了很多差异性.移动互联网时代,head 头部结构 ...
- glusterFS分布式文件系统的搭建
准备工作 1.安装IBA yum install libradmacm librdmacm-devel libmlx4 infiniband-diags 2.配置IPOIB /etc/sysconfi ...
- TP3.1 中URL和APP区别
1.__URL__指当前模块地址,就是当前的action的地址.(每个__action都是一个模块) eg:当前打开config.html,那么config.html里边的__URL__/sav ...