您现在的位置是: 首页 > 软件更新 软件更新

winsocket编程_winsocket教学

tamoadmin 2024-09-21 人已围观

简介1.用Delphi实现WinSocket高级应用2.请高手,WINAPI中socket如何指定同步和异步3.如何在Windows环境下的VS中安装使用Google Protobuf完成SOCKET通信4.socket编程在windows和linux下的区别Winsocket是windows socket的简写,是指Windows下网络编程的规范。Windows Sockets是Windows下得到

1.用Delphi实现WinSocket高级应用

2.请高手,WINAPI中socket如何指定同步和异步

3.如何在Windows环境下的VS中安装使用Google Protobuf完成SOCKET通信

4.socket编程在windows和linux下的区别

winsocket编程_winsocket教学

Winsocket是windows socket的简写,是指Windows下网络编程的规范。

Windows Sockets是Windows下得到广泛应用的、开放的、支持多种协议的网络编程接口。从1991年的1.0版到1995年的2.0.8版,经过不断完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成为Windows网络编程的事实上的标准。

Windows Sockets规范以U.C. Berkeley大学BSD UNIX中流行的Socket接口为范例定义了一套microsoft Windows下网络编程接口。

扩展资料:

Windows Sockets模型中,把所有比较靠下面的层次称为网络系统,把靠上面的层次称为WinSock应用程序,而WinSock的应用编程接口(API)位于两者之间。

动态链接库(DLL)是windows的重要特性,动态链接库是带有定义明确的接口的可执行过程的库,就像其名称所提示的那样,应用程序是在运行时动态链接这些库的,而不是在编译时静态链接。

百度百科-windows socket

用Delphi实现WinSocket高级应用

socket库函数的头文件是

#include <winsock.h>

附录二 Windows Sockets头文件

头文件winsock.h 包含了由Windows Sockets规范所使用的类型和结构定义,常数,宏以及函数原型。Windows Sockets应用程序只要在源文件中包含了winsock.h即可,而不必包含为Berkeley软件的移植而提供的兼容头文件。

头文件winsock.h 包含了标准Windows头文件windows.h的一些类型和定义。在Windows 3.0 SDK (Software Developer's Kit)的头文件windows.h 中缺少 #include 保护,因此应用程序必须象包含winsock.h 一样包含windows.件, 你应该象下面一样在#including winsock.h之前定义符号_INC_WINDOWS:

#include <windows.h>

#define _INC_WINDOWS

#include <winsock.h>

SDK for Windows 3.1 及其以后版本的用户不必这样做。

头文件winsock.h由Windows Sockets规范定义并提供,任何Window Sockets实现都必须和它保持一致。下面列出了winsock.h的内容:

/* WINSOCK.H--definitions to be used with the WINSOCK.DLL

*

* This header file corresponds to version 1.1 of the Windows Sockets specification.

请高手,WINAPI中socket如何指定同步和异步

 Socket通信在Windows 中是排队的形式由操作系统处理 而且接收方和发送方相互协同工作 否则就会造成数据丢失 因此 不能用类似于for 语句的循环来实现对多组数据的发送 更不能用循环语句来接收数据 比如 你可以用for 语句来实型若干文件的复制 这很普遍也很正常 但在 Socket编程以及大多数网络应用编程中都是行不通的 因为网络通信的基本方式是请求和应答 另外 和所有的通信编程一样 Socket编程也遵循数据分包传送这一基本规则 也就是说 在 Socket编程中 每次发送和接收一个包 以保证数据传输的安全性和稳定性 同时也不至于过多地占用系统

 对于ClientSocket组件 从字面上就可以看出 它用于请求方 也就是说 它的动作是主动地建立连接 显然 ServerSocket组件用于响应方 它的动作是侦听以及被动接受连接

 组件ClientSocket的属性是相对静态的 它和ServerSocket之间只是连接和断开的关系 并且仅当ServerSocket对其接受才表示建立连接

 组件ServerSocket的属性是动态的 伴随着一个新的ClientSocket与之建立连接的同时 就会产生一个新的Socket与该ClientSocket对应 保持单独的连接 进行单独的通信 因此 在同一个 ServerSocket中 可以与多个ClientSocket保持同时连接和各自独立的通信 ServerSocket的属性 Socket ActiveConnections用于表示客户端连接的数量 属性Socket Connections[Index] 则用于访问单个与ClientSocket连接的Socket

 正是这样的结构 才使得WinSocket 技术能够稳定实现一个服务程序向多个客户端提供服务

 在独立的ClientSocket中 属性Socket Data 是一个指针 缺省值是nil 在ServerSocket的每个独立的Socket Connections[Index]中 属性Data也是一个指针 缺省值是nil 因此 可以通过该指针建立并保存各自独立的相关信息 用于实现各自独立的通信 而在ClientSocket的 OnRead中 调用方法传递的Socket值就是响应该的对象属性ClientSocket Socket 同样 在 ServerSocket的OnClientRead中 调用方法传递的参数Socket就是对应于当前发送数据客户端的唯一的Socket连接 即ServerSocket Socket Connections[Index] 这样 就能够对不同的连接分得清清楚楚明明白白

 首先介绍实例程序的设计思想 上传文件的过程是这样的(这里的C和S分别代表客户端和服务器端)

 C 请求上传文件 S 准备就绪 可以接收 C 需要上传的文件信息 S 收到文件信息 C 第一个包 S 收到第一个包 创建文件 开始写数据 C 中间的包 S 收到中间的包 继续写数据 C 发送最后一个包 关闭文件 S 收到最后一个包 写数据 关闭文件 下载文件的过程是这样的

 C 请求下载文件 S 准备就绪 可以下载 C 需要下载的文件信息(文件名) S 反馈文件信息(文件大小) C 准备就绪 可以接收数据 S 第一个包 C 收到第一个包 创建文件 开始写数据 S 中间的包 C 收到中间的包 继续写数据 S 发送最后一个包 关闭文件 C 收到最后一个包 写数据 关闭文件 下载成功 S 下载成功 其中 发送中间的包和收到中间的包根据包的数量可以重复 不难看出 上面的两个过程是典型的 你一句我一句 的应答方式

 下面是客户端应用程序和服务器端应用程序的结构 客户端应用程序包括

Client DPR uClient PAS( DFM)(一个ClientSocket组件 一个按钮 一个标签 一个进度条) uClientMain PAS( DFM)(用于选择文件的一组控件和一个Edit控件 三个按钮) uSocketCommon PAS 服务器端应用程序包括

Server DPR uServer PAS( DFM)(一个ServerSocket组件 一个Memo控件 两个按钮) uSocketCommon PAS 其中 单元uSocketCommon 中包括了Socket编程的主要代码 是客户端应用程序和服务器端应用程序都需要的

 结合本例 可以对Delphi中的WinSocket编程作如下总结

lishixinzhi/Article/program/Delphi/201311/25007

如何在Windows环境下的VS中安装使用Google Protobuf完成SOCKET通信

WINAPI中socket原型如下

SOCKET WSAAPI socket(

__in int af,

__in int type,

__in int protocol

);

type类型可以指定为SOCK_STREAM(TCP)、SOCK_DGRAM(UDP)类型。无法在此函数中指定通信方式为同步或异步。

WSAAsyncSelect()函数可以指定某socket为异步模式

原型:

int WSAAsyncSelect(

__in SOCKET s,

__in HWND hWnd,

__in unsigned int wMsg,

__in long lEvent

);

socket编程在windows和linux下的区别

1.下载protobuff,我下的是2.3.0版本

最新的protobuf可以到Google Code上下载:://code.google/p/protobuf/downloads/list

当前版本为2.3.0,下载两个压缩包:protoc-2.3.0-win32.zip和protobuf-2.3.0.zip,前者是protobuf的编译器,后者包含了有三程序语言的开发包。

2.解压

首先解压protoc-2.3.0-win32.zip,把protoc.exe文件放到path路径中,最简单的做法就是把这个文件拷贝到C:/WINDOWS目录下。

解压protobuf-2.3.0.zip文件,将文件加压到C盘根目录,主文件位于C:/protobuf-2.3.0/protobuf-2.3.0目录下。

3.安装操作

(1)使用VS2005编译proto,VS工程目录位于vsprojects目录中,工程名字为“protobuf.sln”。

(2)选择“生成”à“生成解决方案”选项进行编译,编译过程中可能会由于编译的顺序报错误,可以使用手工逐个顺序编译生成,可能会比较顺利。按照下图的顺序,右键“重新生成”,逐个编译。但是我在实习操作过程中,libprotobuf-lite工程重来都没有成功编译通过过。淡定先,这个不会影响大局的。

(3)编译完成会在目录vsprojects下的Debug目录中生成lib和exe文件。

生成清单如下:

exe文件:

2010-04-15 09:51 950,272 lite-test.exe

2010-04-15 09:50 3,219,456 protoc.exe

2010-04-15 09:48 9,228,288 tests.exe

2010-04-15 09:56 2,519,040 test_plugin.exe

lib文件:

2010-04-15 09:50 2,685,922 libprotobuf-lite.lib

2010-04-15 09:56 24,100,794 libprotobuf.lib

2010-04-15 09:56 17,302,068 libprotoc.lib

其实我在测试过程中,lite-test.exe和libprotobuf-lite.lib并没有生成,因为编译错误了,但这并不影响大局,淡定先。

(4)OK,至此,我们已经完成了编译工作,下面需要进行的是protobuf的测试。我们需要使用到之前VS编译出来的libprotobuf.lib和libprotoc.lib完成一个C/S结构的SOCKET通信测试。

àProtobuf的测试

在VS2005下,创建两个新的工程,分别命名为server和client,每个工程都需要引用protobuf的头文件和lib文件。

一、添加protobuf头文件操作:右击项目à属性à配置属性àC/C++à常规 (也命令行可在中添加)。具体路径:C:/protobuf-2.3.0/protobuf-2.3.0/src

二、添加protobuf的lib文件操作:右击项目à属性à配置属性à链接器à常规(也可在命令行中添加)。具体路径:C:/protobuf-2.3.0/protobuf-2.3.0/vsprojects/Debug

三、CMD窗口下编译生成头文件:

C:/protobuf-2.3.0/protobuf-2.3.0/examples>protoc -I=./ --cpp_out=./ people.proto

将proto文件生成的文件放到当前目录。

下面大概分几个方面进行罗列:

Linux要包含

[cpp]

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <arpa/inet.h>

等头文件,而windows下则是包含

[cpp]

#include <winsock.h>

Linux中socket为整形,Windows中为一个SOCKET。

Linux中关闭socket为close,Windows中为closesocket。

Linux中有变量socklen_t,Windows中直接为int。

因为linux中的socket与普通的fd一样,所以可以在TCP的socket中,发送与接收数据时,直接使用read和write。而windows只能使用recv和send。

设置socet选项,比如设置socket为非阻塞的。Linux下为

[cpp]

flag = fcntl (fd, F_GETFL);

fcntl (fd, F_SETFL, flag | O_NONBLOCK);

,Windows下为

[cpp]

flag = 1;

ioctlsocket (fd, FIONBIO, (unsigned long *) &flag);

当非阻塞socket的TCP连接正在进行时,Linux的错误号为EINPROGRESS,Windows的错误号为WSAEWOULDBLOCK。

file

Linux下面,文件换行是"\n",而windows下面是"\r\n"。

Linux下面,目录分隔符是"/",而windows下面是"\"。

Linux与Windows下面,均可以使用stat调用来查询文件信息。但是,Linux只支持2G大小,而Windows只支持4G大小。为了支持更大的文件查询,可以在Linux环境下加

_FILE_OFFSET_BITS=64定义,在Windows下面使用_stat64调用,入参为struct __stat64。

Linux中可根据stat的st_mode判断文件类型,有S_ISREG、S_ISDIR等宏。Windows中没有,需要自己定义相应的宏,如

[cpp]

#define S_ISREG(m) (((m) & 0170000) == (0100000))

#define S_ISDIR(m) (((m) & 0170000) == (0040000))

Linux中删除文件是unlink,Windows中为DeleteFile。

time

Linux中,time_t结构是长整形。而windows中,time_t结构是64位的整形。如果要在windows始time_t为32位无符号整形,可以加宏定义,_USE_32BIT_TIME_T。

Linux中,sleep的单位为秒。Windows中,Sleep的单位为毫秒。即,Linux下sleep (1),在Windows环境下则需要Sleep (1000)。

Windows中的timecmp宏,不支持大于等于或者小于等于。

Windows中没有struct timeval结构的加减宏可以使用,需要手动定义:

[cpp]

#define MICROSECONDS (1000 * 1000)

#define timeradd(t1, t2, t3) do { \

(t3)->tv_sec = (t1)->tv_sec + (t2)->tv_sec; \

(t3)->tv_usec = (t1)->tv_usec + (t2)->tv_usec % MICROSECONDS; \

if ((t1)->tv_usec + (t2)->tv_usec > MICROSECONDS) (t3)->tv_sec ++; \

} while (0)

#define timersub(t1, t2, t3) do { \

(t3)->tv_sec = (t1)->tv_sec - (t2)->tv_sec; \

(t3)->tv_usec = (t1)->tv_usec - (t2)->tv_usec; \

if ((t1)->tv_usec - (t2)->tv_usec < 0) (t3)->tv_usec --, (t3)->tv_usec += MICROSECONDS; \

} while (0)

调用进程

Linux下可以直接使用system来调用外部程序。Windows最好使用WinExec,因为WinExec可以支持是打开还是隐藏程序窗口。用WinExec的第二个入参指明,如

SW_SHOW/SW_HIDE。

杂项

Linux为srandom和random函数,Windows为srand和rand函数。

Linux为snprintf,Windows为_snprintf。

同理,Linux中的strcasecmp,Windows为_stricmp。

错误处理

Linux下面,通常使用全局变量errno来表示函数执行的错误号。Windows下要使用GetLastError ()调用来取得。

Linux环境下仅有的

这些函数或者宏,Windows中完全没有,需要用户手动实现。

atoll

[cpp]

long long

atoll (const char *p)

{

int minus = 0;

long long value = 0;

if (*p == '-')

{

minus ++;

p ++;

}

while (*p >= '0' && *p <= '9')

{

value *= 10;

value += *p - '0';

p ++;

}

return minus ? 0 - value : value;

}

gettimeofday

[cpp]

#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)

#define EPOCHFILETIME 11644473600000000Ui64

#else

#define EPOCHFILETIME 11644473600000000ULL

#endif

struct timezone

{

int tz_minuteswest;

int tz_dsttime;

};

int

gettimeofday (struct timeval *tv, struct timezone *tz)

{

FILETIME ft;

LARGE_INTEGER li;

__int64 t;

static int tzflag;

if (tv)

{

GetSystemTimeAsFileTime (&ft);

li.LowPart = ft.dwLowDateTime;

li.HighPart = ft.dwHighDateTime;

t = li.QuadPart; /* In 100-nanosecond intervals */

t -= EPOCHFILETIME; /* Offset to the Epoch time */

t /= 10; /* In microseconds */

tv->tv_sec = (long) (t / 1000000);

tv->tv_usec = (long) (t % 1000000);

}

if (tz)

{

if (!tzflag)

{

_tzset ();

tzflag++;

}

tz->tz_minuteswest = _timezone / 60;

tz->tz_dsttime = _daylight;

}

return 0;

}

编译相关

当前函数,Linux用__FUNCTION__表示,Windows用__func__表示。

--------------------------------------------------------------------------------

Socket 编程 windows到Linux代码移植遇到的问题

1)头文件

windows下winsock.h/winsock2.h

linux下sys/socket.h

错误处理:errno.h

2)初始化

windows下需要用WSAStartup

linux下不需要

3)关闭socket

windows下closesocket(...)

linux下close(...)

4)类型

windows下SOCKET

linux下int

如我用到的一些宏:

#ifdef WIN32

typedef int socklen_t;

typedef int ssize_t;

#endif

#ifdef __LINUX__

typedef int SOCKET;

typedef unsigned char BYTE;

typedef unsigned long DWORD;

#define FALSE 0

#define SOCKET_ERROR (-1)

#endif

5)获取错误码

windows下getlasterror()/WSetLastError()

linux下errno变量

6)设置非阻塞

windows下ioctlsocket()

linux下fcntl() <fcntl.h>

7)send函数最后一个参数

windows下一般设置为0

linux下最好设置为MSG_NOSIGNAL,如果不设置,在发送出错后有可 能会导致程序退出。

8)毫秒级时间获取

windows下GetTickCount()

linux下gettimeofday()

3、多线程

多线程: (win)process.h --〉(linux)pthread.h

_beginthread --> pthread_create

_endthread --> pthread_exit

-----------------------------------------------------------------

windows与linux平台使用的socket均继承自Berkeley socket(rfc3493),他们都支持select I/O模型,均支持使用getaddrinfo与getnameinfo实现协议无关编程。但存在细微差别,

主要有:

头文件及类库。windows使用winsock2.h(需要在windows.h前包含),并要链接库ws2_32.lib;linux使用netinet/in.h, netdb.h等。

windows下在使用socket之前与之后要分别使用WSAStartup与WSAClean。

关闭socket,windows使用closesocket,linux使用close。

send*与recv*函数参数之socket长度的类型,windows为int,linux为socklen_t,可预编译指令中处理这一差异,当平台为windows时#define socklen_t unsigned int。

select函数第一个参数,windows忽略该参数,linux下该参数表示集合中socket的上限值,一般设为sockfd(需select的socket) + 1。

windows下socket函数返回值类型为SOCKET(unsigned int),其中发生错误时返回INVALID_SOCKET(0),linux下socket函数返回值类型int, 发生错误时返回-1。

另外,如果绑定本机回环地址,windows下sendto函数可以通过,linux下sendto回报错:errno=22, Invalid arguement。一般情况下均绑定通配地址。

转载jlins