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 ...
随机推荐
- 表单提交set集合问题
提交时使用数组接收,遍历将数组添加到set集合 用户表user 字段id,name,set<xk> xks=new HashSet<xk>(); 选课表xk 字段id,name ...
- One Night Ultimate Werewolf Daybreak
http://beziergames.com/products/replacement-tiles-tokens-for-one-night-ultimate-werewolf http://www. ...
- FBX
http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/index.html http://forums.autodesk.com/t5 ...
- Bindless Textures
http://shikihuiku.wordpress.com/2014/02/10/openglのtextureについて/
- ecshop 后台【左侧新增菜单】
模板文件admin/template/menu.htm admin/includes/inc_menu.php 菜单排序(链接) langagues/zh_cn/admin/common.php 语 ...
- Hive部署
前置环境:CentOS 6.5 + JDK 1.7 + Hadoop 2.6 注:此处采用伪分布安装Hadoop,平时测试使用,Hive的元数据信息使用MySQL存储 一.安装MySQL 1.检查是否 ...
- Java多线程编程核心技术---拾遗增补
线程状态验证 public class MyThread extends Thread { public MyThread() { System.out.println("构造方法中的状态: ...
- spring的PathMatchingResourcePatternResolver-通配符的Resource查找器
PathMatchingResourcePatternResolver是一个通配符的Resource查找器,包括: /WEB-INF/*-context.xml com/mycompany/**/ap ...
- C语言strdup函数
static RD_INLINE RD_UNUSED char *rd_strdup(const char *s) { #ifndef _MSC_VER char *n = strdup(s); #e ...
- 配置 nginx server 出现nginx: [emerg] "root" directive is duplicate in /etc/nginx/server/blogs.conf:7
在配置nginx 虚拟机时,执行 sudo /usr/sbin/nginx -t 报下面的错误: nginx: [emerg] nginx: configuration file /etc/nginx ...