windows下的socket网络编程

时间:2022-10-07 11:09:13

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的,因为都是局域网内,就简单的写了个。
这里是在虚拟机里面测试的截图,代码见最后。

windows下的socket网络编程

代码如下

这是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网络编程的更多相关文章

  1. windows下的socket网络编程(入门级)

    windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了,这次因为需要做一个跨平台的网络程序,就先 ...

  2. Cfree clion windows c语言 socket 网络编程

    server.c #include <stdio.h> #include <winsock2.h> #define SERVER_PORT 5208 //侦听端口 int ma ...

  3. winsock教程- windows下的socket编程(c语言实现)

    winsock教程- windows下的socket编程(c语言实现) 使用winsock进行socket 编程     这是一个学习windows下socket编程(c语言)的快速指南.这是因为一下 ...

  4. windows socket网络编程基础知识

    下面介绍网络7层协议在WINDOWS的实现: 7层协议 WIN系统 ________________________________________ 7 应用层 7 应用程序 ____________ ...

  5. windows socket 网络编程

    样例代码就在我的博客中,包含六个UDP和TCP发送接受的cpp文件,一个基于MFC的局域网聊天小工具project,和此小工具的全部执行时库.资源和执行程序.代码的压缩包位置是http://www.b ...

  6. linux下C语言socket网络编程简例

    原创文章,转载请注明转载字样和出处,谢谢! 这里给出在linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到client的连接后,发送数据给client:clie ...

  7. 5&period;3linux下C语言socket网络编程简例

    原创文章,转载请注明转载字样和出处,谢谢! 这里给出在Linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到客户端的连接后,发送数据给客户端:客户端在接受到数据后 ...

  8. 项目总结——深入浅出socket网络编程

    前言: 为什么会有如题的概念呢,我想对于没有主动听说过socket网络编程的人来说读到题目可能就已经蒙头了,为了很好的让大家进入场景,首先说一下一个需要用到这点东西的业务需求. 首先大家应该明确的是s ...

  9. Socket网络编程详解

    一,socket的起源 socket一词的起源 在组网领域的首次使用是在1970年2月12日发布的文献IETF RFC33中发现的, 撰写者为Stephen Carr.Steve Crocker和Vi ...

随机推荐

  1. SqlServer -- 仅当使用了列列表并且 IDENTITY&lowbar;INSERT 为 ON 时,才能为表&&num;39&semi;T&lowbar;FM&lowbar;AMTFLOW&&num;39&semi;中的标识列指定显式值。

    SET IDENTITY_INSERT TABLE_NAME ON; INSERT INTO TABLE_NAME(XXX, XXX,..., XXX) SELECT XXX, XXX,..., XX ...

  2. footer置底

    html代码: <div class="container"> <div cass="header"></div> < ...

  3. Google 云计算中的 GFS 体系结构

          google 公司的很多业务具有数据量巨大的特点,为此,google 公司研发了云计算技术.google 云计 算结构中的 google 文件系统是其云计算技术中的三大法宝之一.本文主要介 ...

  4. PL&sol;SQL设置快捷键

    PL/SQL常用的快捷方式: sf= select * from sr=select t.*,t.rowid from t sd = select distinct * from d=delete f ...

  5. 深入浅出Mybatis-与Spring集成

    单独使用mybatis是有很多限制的(比如无法实现跨越多个session的事务),而且很多业务系统本来就是使用spring来管理的事务,因此mybatis最好与spring集成起来使用. 前置要求 版 ...

  6. Restful 支持 自定义序列化

    [ServiceContract] [ServiceKnownType(typeof(HRAwardObject))] [ServiceKnownType(typeof(WorkflowBasicIn ...

  7. LU分解,Javascript代码

    ///A 为矩阵,这里写成一维数组,如 [1],[1,2,3,4] function GetLU(a) { var n = a.length;//矩阵的总数据数目 var s = Math.sqrt( ...

  8. C&num;Linq中的Union All&sol;Union&sol;Intersect和Top&sol;Bottom和Paging和SqlMethods&comma;skip&comma;take&comma;takewhile&comma;skipwhile&comma;编译查询等

    我们继续讲解LINQ to SQL语句,这篇我们来讨论Union All/Union/Intersect操作和Top/Bottom操作和Paging操作和SqlMethods操作 . Union Al ...

  9. node&period;js 包教不包会 (Windows版详解)

    针对@alsotang 的新手入门教程 https://github.com/alsotang/node-lessons ,详解该教程在Windows中的实践,包括博主在实践过程中遇到的问题及解决方案 ...

  10. Java:编码的详解

    ASCII:美国信息标准信息码,用一个字节的7为表示. ISO8859-1:拉丁码表 欧洲码表 ,用一个字节的8位表示. GB2312:中国的中文编码表. GBK:中国的中文编码表升级,融合了更多的中 ...