首页编程socket编程在哪里写 Socket的创建和监听方法

socket编程在哪里写 Socket的创建和监听方法

编程之家2026-05-27751次浏览

很多朋友对于socket编程在哪里写和Socket的创建和监听方法不太懂,今天就由小编来为大家分享,希望可以帮助到大家,下面一起来看看吧!

socket编程在哪里写 Socket的创建和监听方法

windows下socket如何编程

一个简单的TCP客户端程序流程

1、使用WSAStartup()初始化WinSock库。

2、使用socket()创建一个IPPROTO_TCP SOCKET。

3、使用gethostbyname()/gethostbyaddr()获取主机信息。

4、使用connect()和我们创建的套接字连接服务器。

5、使用send()/recv()发送和接收数据,直到我们的TCP会话结束。

socket编程在哪里写 Socket的创建和监听方法

6、使用closesocket()关闭套接字连接。

7、使用WSACleanup()释放WinSock。

初始化WinSock

正如其它每个WinSock程序一样,我们需要初始化WinSock库。这也基本上是一种检查WinSock是否在当前系统可用的方法,对于以前的版本,我们当然希望是这样。

int wsaret=WSAStartup(0x101,&wsaData);

if(wsaret)

socket编程在哪里写 Socket的创建和监听方法

return;

创建SOCKET

套接字是一种实体,它担当了客户端和服务器之间的端点。当客户端连接到服务器之后,就会存在两个套接字——客户端一边的套接字和相应的服务器一边的套接字。让我们来称它们为CLIENTSOCK和SERVERSOCK。当客户端在CLIENTSOCK使用send()时,服务器可以在SERVERSOCK使用recv()来接收客户端所发送的数据,反之亦然。对于我们的目的,我们使用一个名为socket()的函数来创建套接字。

SOCKET conn;

conn=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if(conn==INVALID_SOCKET)

return;

获取主机信息

显然,我们在连接到主机(服务器)之前,要获取它的信息。我们可以使用两个函数——gethostbyname()和gethostbyaddr()。当我们拥有服务器的DNS名称时,我们可以使用gethostbyname()函数,例如codeproject.com或ftp.myserver.org之类的名称。当我们拥有要连接的服务器的IP地址时,可以使用gethostbyaddr()函数,例如192.168.1.1或202.54.1.100。

显然,我们希望能使我们的最终用户既能使用DNS名称,也能使用IP地址。那么,为了这些工作对他来说透明,我们需要像下面这样玩一个小把戏。我们对入口字符串使用inet_addr(),这个函数会把一个IP地址转换成一个标准的网络地址格式。这样一来,如果它返回失败,我们就可以知道这个字符串不是一个IP地址,如果它成功的话,我们就可以假设它是一个有效的IP地址了。

if(inet_addr(servername)==INADDR_NONE)

{

hp=gethostbyname(servername);

}

else

{

addr=inet_addr(servername);

hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);

}

if(hp==NULL)

{

closesocket(conn);

return;

}

连接到服务器

connect()函数用于向目标服务器建立连接。我们向它传递我们先前创建的套接字和一个sockaddr结构。我们使用由gethostbyname()/gethostbyaddr()返回的主机地址为sockaddr成员赋值,并输入一个要连接的有效端口。

server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);

server.sin_family=AF_INET;

server.sin_port=htons(80);

if(connect(conn,(struct sockaddr*)&server,sizeof(server)))

{

closesocket(conn);

return;

}

会话

当套接字连接建立后,客户端和服务器就可以通过send()和recv()来发送/接收数据了。这通常称为TCP会话。对于我们的特定情况,我们需要进行HTTP会话。和那些复杂的SMTP或POP3协议相比,它还是比较简单的。HTTP的GET命令用于从HTTP服务器上获取文件。这个文件可以是HTML文件、图像文件、压缩文件、MP3文件等等。这样,这个文件就会被发送了(这是它最简单的形式)。当然,还有一些更复杂的方法来使用这个命令。

GET http-path-to-file\r\n\r\n

在我们的程序中,我们像这样来发送GET命令:

sprintf(buff,"GET%s\r\n\r\n",filepath);

send(conn,buff,strlen(buff),0);

当我们发送了这个命令的时候,我们就应该知道服务器就要开始把我们所请求的文件发送给我们了。就像我们使用send()来发送我们的命令一样,我们可以使用recv()来接收服务器发送给我们的数据。我们循环调用recv(),直到它返回零,这时候我们就会知道服务器已经将数据发送完毕了。并且,对于我们的特定情况,我们可以将这些数据写入文件,就像我们要下载并保存这个文件一样。

while(y=recv(conn,buff,512,0))

{

f.Write(buff,y);

}

关闭连接

现在我们的会话结束了,我们必须关闭连接。在我们的情况下,HTTP连接在文件发送完毕之后就会被服务器关闭了,但是这不要紧,我们仍然需要关闭我们的套接字并释放资源。在更加复杂的会话中,我们通常在调用closesocket()之前调用shutdown()来确定缓冲区已经被刷新,否则可能会有部分数据丢失。

closesocket(conn);

释放WinSock

我们调用WSACleanup()来结束WinSock的使用。

WSACleanup();

socket编程到底是什么

socket其实就是操作系统提供给程序员操作「网络协议栈」的接口,说人话就是,你能通过socket的接口,来控制协议找工作,从而实现网络通信,达到跨主机通信。

协议栈的上半部分有两块,分别是负责收发数据的 TCP和 UDP协议,它们两会接受应用层的委托执行收发数据的操作。

协议栈的下面一半是用 IP协议控制网络包收发操作,在互联网上传数据时,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由 IP负责的。这里需要注意的是,服务端调用 accept时,连接成功了会返回一个已完成连接的 socket,后续用来传输数据。

所以,监听的 socket和真正用来传送数据的 socket,是「两个」 socket,一个叫作监听 socket,一个叫作已完成连接 socket。成功连接建立之后,双方开始通过 read和 write函数来读写数据,就像往一个文件流里面写东西一样。

socket编程在windows和linux下的区别

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

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()/WSAGetLastError()

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

OK,关于socket编程在哪里写和Socket的创建和监听方法的内容到此结束了,希望对大家有所帮助。

app制作一个需要多少钱?开发一个app软件需要多少钱网页编程代码大全,html网页制作代码大全