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/recvfrom3、清理
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 ...
随机推荐
- ecshop Admin后台商品列表处(上架、下架、精品...取消精品)增加操作
相关文件:goods.php,goods_list.htm 思路: a.增添连接“转移仓库” b.在goods.php,读取仓库列表数据,并且实例化 c. 在goods_list.htm循环数据.点击 ...
- Unity 下载
Unity历史版本 http://wiki.ceeger.com/unity:history#unity_522f1 UNITY 下载存档 http://unity3d.com/cn/get-unit ...
- yum提示字符编码错误
1.问题描述: [root@localhost data]# yum Loaded plugins: product-id, refresh-packagekit, security, subscri ...
- tar: 由于前次错误,将以上次的错误状态退出
1.安装cmake的源码包,出现以下错误提示: # tar -zxvf cmake-3.2.2.tar.gz cmake-/Source/cmCommandArgumentParser.cxx tar ...
- python 默认全局变量
python 内置默认全局变量print (vars()) __doc__ #py文件头部的注释 '''我是一个注释例子''' print (vars()) __file__ #当前文件路劲__pac ...
- [MySQL FAQ]系列 — 为什么InnoDB表要建议用自增列做主键
我们先了解下InnoDB引擎表的一些关键特征: InnoDB引擎表是基于B+树的索引组织表(IOT): 每个表都需要有一个聚集索引(clustered index): 所有的行记录都存储在B+树的叶子 ...
- MobClick详解
1.使用自定义事件 使用自定义事件功能请先在网站应用管理后台(设置->编辑自定义事件)中添加相应的自定义事件后,服务器才会对相应的自定义事件请求进行处理.这里我们将提供几个简单而通用的接口: 1 ...
- JavaScript基础整理(2)
接下来的重点是函数.我们知道函数是特殊的对象. 函数作用域和声明提前.JavaScript中没有块级作用域,只有函数作用域:变量在声明它们的函数体以及这个函数体嵌套的任意 函数体内都要定义. func ...
- 【8-18】JS学习01
Source : http://www.w3school.com.cn/html 外部的 JavaScript 也可以把脚本保存到外部文件中.外部文件通常包含被多个网页使用的代码. 外部 JavaSc ...
- Java Programming Test Question 4
What will be the boolean flag value to reach the finally block? public class JPTQuestion4 { public s ...