windows sock 网络编程基础知识--基本TCP套接字编程
2012-10-16 00:21
567 查看
#include "winsock2.h"//头文件
#pragma comment(lib, "wsock32.lib")//导入wsock32.lib库文件
TCP和UDP的区别
简单的说,就是有建立连接(TCP)和无建立连接(UDP)。
typedef unsigned int u_int; //u_int 为无符号整形
typedef u_int SOCKET; //SOCKET为无符号整形,称为套接字
在windows Sockets中除了INVALID_SOCKET不是一个有效的套接字外,在0-INVALID_SOCKET-1之间的数值
都是有效的套接字。
判断是否成功的创建了套接字的方法是将socket()函数的返回值与INVALID_SOCKET进行比较
eg:
SOCKET s = socket(...);
if (INVALID_SOCKET == s)
{
//失败
}
INVALID_SOCKET 的声明如下:
#define INVALID_SOCKET (SOCKET)(~0) //~为按位取反运算符,在32位中INVALID_SOCKET为-1
在32位系统中对于0全部取反就是 1111 1111 1111 1111 等于-1。 简单记忆:0+1取反等于-1
常量SOCKET_ERROR是被用来检查Windows API调用失败的。
SOCKET_ERROR的声明如下:
#define SOCKET_ERROR (-1)
Windows Sockets API 提供了shutdown()和WSASendDisconnect()函数实现关闭连接的功能。
closesocket()函数实现关闭套接字的功能,但同时也隐含执行shutdown()函数的功能。
Windows Sockets 通过AF_INET地址家族为IP通信定址。其中“A”代表address,“F”代表family。
AF_INET的声明如下:
#define AF_INET 2;
Windows Sockets API提供了SOCKADDR_IN结构来指定IP地址和端口号
该结构声明如下:
struct sockaddr_in{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
sin_famliy: 地址家族
sin_port: 服务端口号
sin_addr: in_add类型的IP地址
sin_zero: 填充该结构的大小,使之与SOCKADD结构大小相同
sin_family字段必须为AF_INET,以告知Windows Sockets应用程序使用IP地址家族。
sin_port字段指定了服务的端口号。1024-49151
sin_addr字段用于把一个IP地址保存为一个4字节的数值
sin_zero字段充当填充项的职责,以便使得该结构与SOCKADDR结构长度相同
字节顺序问题
在计算机中把IP地址和端口号指定为多字节数字时,这个数就按照“主机字节”(hose-byte)顺序表示
。但是在网络上指定IP地址和端口号,这个数必须按照“大头”形式来表示,也就是按照从最有意义的字
节到最无意义的字节来表示数据,这里称为“网络字节”顺序(network-byte)
htonl()函数和htons()函数实现从主机字节顺序转换为网络字节顺序的功能。其中“h”代表机“host”
;“n”代表“net”;“l”代表“long”;“s”代表“short”;“to”表示转换的含义。
htonl()函数和htons()函数声明如下。
u_long htohl(u_long hostlong);
u_short htohs(u_short hostshort);
ntohl()函数和ntohs()函数实现从网络字节顺序转换为主机字节顺序的功能。
ntohl()函数和ntohs()函数声明如下。
u_long ntohl(u_long netlong);
ushort ntohs(u_short netshort);
客户端连接服务器时,必须先知道服务器的名称。
在TCP/IP中,服务器的名称 = 服务器的IP地址和端口号。
服务端--创建套接字--绑定--监听--接受连接--发送数据--关闭
bind()函数实现将服务器绑定到一个已知的名字上的功能。
接下来需要将服务器套接字设置为监听状态,以便监听客户端的连接,这是通过调用listen()函数完成的
在监听状态下,如果客户端向服务器发起连接请求,服务器通过调用accetp()函数来接受该连接请求
服务端与客户端完成连接后,借可以进行数据通信了。
客户端--创建套接字--连接--发送数据--关闭
调用connect()函数向服务器发出连接请求。
WSAStartup()函数
开发Windows Sockets应用程序时,必须首先加载Windows Sockets动态库(DLL)。WSAStartup()函数实
现此项功能。该函数是套接字应用程序必须调用的第一个函数。
该函数的声明如下:
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
wVersionRequested:指定准备加载Windows Sockets动态库的版本。
lpWSAData:指向LPWSADATA结构的指针,该参数返回被加载动态库的有关信息。
WSADATA结构声明如下:
#define WSADESCRIPTION_LEN 256
#define WSASYS_STATUS_LEN 128
typedef struct WSAData
{
WORD wVersion;
WORD wHigtVersion;
char szDescription{WSADESCRIPTION_LEN+1};
char szSystemStatus{WSASYS_STATUS_LEN+1};
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR* lpVendorInfo;
}WSADATA, FAR * LPWSADATA;
wVersion:期望调用者使用的Windows Sockets版本
wHighVersion:DLL支持的最高版本
szDescription:DLL的描述信息
szSystemStatus:DLL的状态信息
iMaxSockets:一个进程可以打开的套接字最多数量(Windows Sockets2.0及以后版本中忽略此值)
iMaxUdpDg:一个进程发送或接收的最大的数据包的长度(Windows Sockets2.0及以后版本中忽略此值)
lpVendorInfo:厂商专有信息(Windows Sockets2.0及以后版本中忽略此值)
socket()函数
初始化Windows Sockets DLL之后,创建套接字。socket()函数和WSASocket()函数将实现此功能。
socket()函数声明如下:
SOCKET socket(int af, int type, int protocol);
af:协议的地址家族。创建TCP或者UDP套接字时,该参数为AF_INET。
type:协议的套接字类型。有SOCK_STREAM,SOCK_DGRAM和SOCK_RAM 3种类型
protocol:协议。指定的地址家族和套接字类型有多个数目时,使用该字段来限定一个特殊的传输。对于
SOCK_STREAM套接字类型,该字段为IPPROTO_TCP或者为0;对于SOCK_DGRAM套接字类型,该字段为
IPPROTO_UDP或者为0.
当该函数调用成功后,返回一个新建的套接字句柄,调用失败则返回INVALID_SOCKET.
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == s)
{
//调用失败
}
bind()函数
bind()函数将套接字绑定到一个已知的地址。
该函数声明如下:
int bind(SOCKET s, const struct sockaddr FAR * name, int namelen);
s:套接字
name:地址
namelen:sockaddr结构长度
如果该函数调用成功,则返回值为0,失败则返回值为SOCKET_ERROR
如果地址字段为INADDR_ANY,则可使用任意网络接口。
如果端口号设置为0,则Windows Sockets将给应用程序分配一个值在1024-5000之间的唯一端口
eg:
SOCKET s;//套接字
struct sockaddr_in servAddr;//服务器套接字地址
int nServPort = 5500;//服务器端口
int nErrCode;//错误代码
//定义服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_addr = htonl(INADDR_ANY);
servAddr.sin_family = htons(nServPort);
//绑定套接字
nErrcode = bind(s, (SOC
4000
KADDR*) &servAddr, sizeof(servAddr));
if(SOCKET_ERROR == nErrCode)
{
//绑定套接字失败
}
listen()函数
listen()函数将套接字设置为监听模式。
listen()函数声明如下:
int listen(SOCKET s, int backlog);
s:套接字
backlog:指定等待连接的最大队列长度
该函数调用成功时,返回值为0,失败则返回SOCKET_ERROR.
accept()函数
accept()函数实现接受一个连接请求的功能
accept()声明如下:
SOCKET accept(SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen);
s:监听套接字。
addr:该参数返回请求连接主机的地址
addrlen:该参数返回SOCKADDR_IN结构的长度。
当该函数成功返回时:
主机接受了等待队列中的第一个请求
addr结构返回发起请求的客户端的地址,addrlen参数指出了地址结构的长度。
返回一个新的套接字句柄。服务器使用该套接字与客户端进行数据传输。而监听套接字仍然用于接受客户
端的连接
调用失败时返回INVALID_SOCKET错误
SOCKET sListen;//监听套接字
SOCKET sAccept;//接受套接字
sockaddr_in addrClient;//客户端地址
int addrClientlen = sizeof(addrClient);//长度
//接受客户请求
sAccept = accept(sListen, (SOCKADDR*) &addrClient, &addrClientlen);
if(INVALID_SOCKET == sAccept)
{
//失败处理
}
recv()函数
recv()和WSARecv()函数用于接受数据
recv()函数声明如下:
int recv(SOCKET s, char FAR * buf, int len, int flags);
s:套接字
buf:接受数据缓冲区
len:缓冲区长度
flags:该参数影响该函数的行为。该参数可以是0,MSG_PEEK和MSG_OOB.0表示无特殊行为;MSG_PEEK会
使有用的数据被复制到接收缓冲区内,但没有从系统缓冲区中将其删除,MSG——OOB表示处理带外数据。
该函数成功返回时返回值为接收的字节数。失败时则返回SOCKET_ERROR.
SOCKET s;//套接字
char buf[128];//接收数据缓冲区
int nReadlen;//接收字节数
//接收数据
nReadlen = recv(s, buf, 128, 0);
if(SOCKET_ERROR == nReadlen)
{
//失败处理
}
send()函数
send()和WSASend()函数用于发送数据
send()函数声明如下:
int send(SOCKET s, const char FAR * buf, int len, int flags);
s:套接字
buf:发送数据缓冲区
len:发送数据长度
flags:该参数影响该函数的行为,该参数可以为0,MSG_DONTROUTE或者MSG_OOB。0表示无函数无特殊行
为,MSG_DONTROUTE标志要求传输层不要将数据路由出去,MSG_OOB标志表示该数据应该被带外发送。
该函数成功返回时,返回值为实际发送的字节数。失败时返回SOCKET_ERROR。
SOCKET s;//套接字
char buf[128];//接受数据缓冲区
int retVal;//返回值
strcpy(buf, "send data");
//发送数据
retVal = send(s, buf, strlen(buf),0);
if(SOCKET_ERROR == retVal)
{
//失败处理
}
closesocket()函数
closesocket()函数关闭套接字,释放所占资源。
该函数输声明如下:
int closesocket(SOCKET s);
当调用该函数释放套接字后,如果在使用该套接字执行函数调用,则会失败并返回WSAENOTSOCK错误。
shutdown()函数
shutdown()函数用于通知对方不再发送数据,或者不再接收数据,或者既不发送也不接收数据
该函数声明如下:
int shutdown(SOCKET s, int how);
s:套接字
how:如果该参数为SD_RECEIVE,则表示不允许再调用接收数据函数;如果该参数为SE_SEND,则表示不允
许再调用发送数据函数;如果该参数为SD_BOTH,则表示既不允许调用发送数据函数也不允许调用接收数
据函数
connect()函数
connect()函数实现连接服务器功能。
该函数声明如下:
int connect(SOCKET s, const struct cockaddr FAR * name, int namelen);
s:套接字
name:服务器地址
namelen:sockaddr结构的长度
当该函数调用成功时,函数返回0,调用失败时返回SOCKET_ERROR.
SOCKET s;//套接字
u_long ulServIP;//服务器IP
u_short usServPort;//服务器端口
int setVal;//返回值
//服务器地址
SOCKADDR_IN servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = htonl(ulServIP);
servAddr.sin_Port = htos(usServPort);
int nServLen = sizeof(servAddr);
//连接服务器
retVal = connect(s, (LPSOCKADDR)&servAddr, sizeof(servAddr));
if(SOCKET_ERROR == retVal)
{
//失败处理
}
开发过程:
Server:
WSAStartup()--socket()--bind()--listen()--accept()--recv()--closesocket--WSACleanup()
Client:
WSAStartup()--socket()--connect()--send()--closesocket()--WSACleanup()
#pragma comment(lib, "wsock32.lib")//导入wsock32.lib库文件
TCP和UDP的区别
简单的说,就是有建立连接(TCP)和无建立连接(UDP)。
typedef unsigned int u_int; //u_int 为无符号整形
typedef u_int SOCKET; //SOCKET为无符号整形,称为套接字
在windows Sockets中除了INVALID_SOCKET不是一个有效的套接字外,在0-INVALID_SOCKET-1之间的数值
都是有效的套接字。
判断是否成功的创建了套接字的方法是将socket()函数的返回值与INVALID_SOCKET进行比较
eg:
SOCKET s = socket(...);
if (INVALID_SOCKET == s)
{
//失败
}
INVALID_SOCKET 的声明如下:
#define INVALID_SOCKET (SOCKET)(~0) //~为按位取反运算符,在32位中INVALID_SOCKET为-1
在32位系统中对于0全部取反就是 1111 1111 1111 1111 等于-1。 简单记忆:0+1取反等于-1
常量SOCKET_ERROR是被用来检查Windows API调用失败的。
SOCKET_ERROR的声明如下:
#define SOCKET_ERROR (-1)
Windows Sockets API 提供了shutdown()和WSASendDisconnect()函数实现关闭连接的功能。
closesocket()函数实现关闭套接字的功能,但同时也隐含执行shutdown()函数的功能。
Windows Sockets 通过AF_INET地址家族为IP通信定址。其中“A”代表address,“F”代表family。
AF_INET的声明如下:
#define AF_INET 2;
Windows Sockets API提供了SOCKADDR_IN结构来指定IP地址和端口号
该结构声明如下:
struct sockaddr_in{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
sin_famliy: 地址家族
sin_port: 服务端口号
sin_addr: in_add类型的IP地址
sin_zero: 填充该结构的大小,使之与SOCKADD结构大小相同
sin_family字段必须为AF_INET,以告知Windows Sockets应用程序使用IP地址家族。
sin_port字段指定了服务的端口号。1024-49151
sin_addr字段用于把一个IP地址保存为一个4字节的数值
sin_zero字段充当填充项的职责,以便使得该结构与SOCKADDR结构长度相同
字节顺序问题
在计算机中把IP地址和端口号指定为多字节数字时,这个数就按照“主机字节”(hose-byte)顺序表示
。但是在网络上指定IP地址和端口号,这个数必须按照“大头”形式来表示,也就是按照从最有意义的字
节到最无意义的字节来表示数据,这里称为“网络字节”顺序(network-byte)
htonl()函数和htons()函数实现从主机字节顺序转换为网络字节顺序的功能。其中“h”代表机“host”
;“n”代表“net”;“l”代表“long”;“s”代表“short”;“to”表示转换的含义。
htonl()函数和htons()函数声明如下。
u_long htohl(u_long hostlong);
u_short htohs(u_short hostshort);
ntohl()函数和ntohs()函数实现从网络字节顺序转换为主机字节顺序的功能。
ntohl()函数和ntohs()函数声明如下。
u_long ntohl(u_long netlong);
ushort ntohs(u_short netshort);
客户端连接服务器时,必须先知道服务器的名称。
在TCP/IP中,服务器的名称 = 服务器的IP地址和端口号。
服务端--创建套接字--绑定--监听--接受连接--发送数据--关闭
bind()函数实现将服务器绑定到一个已知的名字上的功能。
接下来需要将服务器套接字设置为监听状态,以便监听客户端的连接,这是通过调用listen()函数完成的
在监听状态下,如果客户端向服务器发起连接请求,服务器通过调用accetp()函数来接受该连接请求
服务端与客户端完成连接后,借可以进行数据通信了。
客户端--创建套接字--连接--发送数据--关闭
调用connect()函数向服务器发出连接请求。
WSAStartup()函数
开发Windows Sockets应用程序时,必须首先加载Windows Sockets动态库(DLL)。WSAStartup()函数实
现此项功能。该函数是套接字应用程序必须调用的第一个函数。
该函数的声明如下:
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
wVersionRequested:指定准备加载Windows Sockets动态库的版本。
lpWSAData:指向LPWSADATA结构的指针,该参数返回被加载动态库的有关信息。
WSADATA结构声明如下:
#define WSADESCRIPTION_LEN 256
#define WSASYS_STATUS_LEN 128
typedef struct WSAData
{
WORD wVersion;
WORD wHigtVersion;
char szDescription{WSADESCRIPTION_LEN+1};
char szSystemStatus{WSASYS_STATUS_LEN+1};
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR* lpVendorInfo;
}WSADATA, FAR * LPWSADATA;
wVersion:期望调用者使用的Windows Sockets版本
wHighVersion:DLL支持的最高版本
szDescription:DLL的描述信息
szSystemStatus:DLL的状态信息
iMaxSockets:一个进程可以打开的套接字最多数量(Windows Sockets2.0及以后版本中忽略此值)
iMaxUdpDg:一个进程发送或接收的最大的数据包的长度(Windows Sockets2.0及以后版本中忽略此值)
lpVendorInfo:厂商专有信息(Windows Sockets2.0及以后版本中忽略此值)
socket()函数
初始化Windows Sockets DLL之后,创建套接字。socket()函数和WSASocket()函数将实现此功能。
socket()函数声明如下:
SOCKET socket(int af, int type, int protocol);
af:协议的地址家族。创建TCP或者UDP套接字时,该参数为AF_INET。
type:协议的套接字类型。有SOCK_STREAM,SOCK_DGRAM和SOCK_RAM 3种类型
protocol:协议。指定的地址家族和套接字类型有多个数目时,使用该字段来限定一个特殊的传输。对于
SOCK_STREAM套接字类型,该字段为IPPROTO_TCP或者为0;对于SOCK_DGRAM套接字类型,该字段为
IPPROTO_UDP或者为0.
当该函数调用成功后,返回一个新建的套接字句柄,调用失败则返回INVALID_SOCKET.
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == s)
{
//调用失败
}
bind()函数
bind()函数将套接字绑定到一个已知的地址。
该函数声明如下:
int bind(SOCKET s, const struct sockaddr FAR * name, int namelen);
s:套接字
name:地址
namelen:sockaddr结构长度
如果该函数调用成功,则返回值为0,失败则返回值为SOCKET_ERROR
如果地址字段为INADDR_ANY,则可使用任意网络接口。
如果端口号设置为0,则Windows Sockets将给应用程序分配一个值在1024-5000之间的唯一端口
eg:
SOCKET s;//套接字
struct sockaddr_in servAddr;//服务器套接字地址
int nServPort = 5500;//服务器端口
int nErrCode;//错误代码
//定义服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_addr = htonl(INADDR_ANY);
servAddr.sin_family = htons(nServPort);
//绑定套接字
nErrcode = bind(s, (SOC
4000
KADDR*) &servAddr, sizeof(servAddr));
if(SOCKET_ERROR == nErrCode)
{
//绑定套接字失败
}
listen()函数
listen()函数将套接字设置为监听模式。
listen()函数声明如下:
int listen(SOCKET s, int backlog);
s:套接字
backlog:指定等待连接的最大队列长度
该函数调用成功时,返回值为0,失败则返回SOCKET_ERROR.
accept()函数
accept()函数实现接受一个连接请求的功能
accept()声明如下:
SOCKET accept(SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen);
s:监听套接字。
addr:该参数返回请求连接主机的地址
addrlen:该参数返回SOCKADDR_IN结构的长度。
当该函数成功返回时:
主机接受了等待队列中的第一个请求
addr结构返回发起请求的客户端的地址,addrlen参数指出了地址结构的长度。
返回一个新的套接字句柄。服务器使用该套接字与客户端进行数据传输。而监听套接字仍然用于接受客户
端的连接
调用失败时返回INVALID_SOCKET错误
SOCKET sListen;//监听套接字
SOCKET sAccept;//接受套接字
sockaddr_in addrClient;//客户端地址
int addrClientlen = sizeof(addrClient);//长度
//接受客户请求
sAccept = accept(sListen, (SOCKADDR*) &addrClient, &addrClientlen);
if(INVALID_SOCKET == sAccept)
{
//失败处理
}
recv()函数
recv()和WSARecv()函数用于接受数据
recv()函数声明如下:
int recv(SOCKET s, char FAR * buf, int len, int flags);
s:套接字
buf:接受数据缓冲区
len:缓冲区长度
flags:该参数影响该函数的行为。该参数可以是0,MSG_PEEK和MSG_OOB.0表示无特殊行为;MSG_PEEK会
使有用的数据被复制到接收缓冲区内,但没有从系统缓冲区中将其删除,MSG——OOB表示处理带外数据。
该函数成功返回时返回值为接收的字节数。失败时则返回SOCKET_ERROR.
SOCKET s;//套接字
char buf[128];//接收数据缓冲区
int nReadlen;//接收字节数
//接收数据
nReadlen = recv(s, buf, 128, 0);
if(SOCKET_ERROR == nReadlen)
{
//失败处理
}
send()函数
send()和WSASend()函数用于发送数据
send()函数声明如下:
int send(SOCKET s, const char FAR * buf, int len, int flags);
s:套接字
buf:发送数据缓冲区
len:发送数据长度
flags:该参数影响该函数的行为,该参数可以为0,MSG_DONTROUTE或者MSG_OOB。0表示无函数无特殊行
为,MSG_DONTROUTE标志要求传输层不要将数据路由出去,MSG_OOB标志表示该数据应该被带外发送。
该函数成功返回时,返回值为实际发送的字节数。失败时返回SOCKET_ERROR。
SOCKET s;//套接字
char buf[128];//接受数据缓冲区
int retVal;//返回值
strcpy(buf, "send data");
//发送数据
retVal = send(s, buf, strlen(buf),0);
if(SOCKET_ERROR == retVal)
{
//失败处理
}
closesocket()函数
closesocket()函数关闭套接字,释放所占资源。
该函数输声明如下:
int closesocket(SOCKET s);
当调用该函数释放套接字后,如果在使用该套接字执行函数调用,则会失败并返回WSAENOTSOCK错误。
shutdown()函数
shutdown()函数用于通知对方不再发送数据,或者不再接收数据,或者既不发送也不接收数据
该函数声明如下:
int shutdown(SOCKET s, int how);
s:套接字
how:如果该参数为SD_RECEIVE,则表示不允许再调用接收数据函数;如果该参数为SE_SEND,则表示不允
许再调用发送数据函数;如果该参数为SD_BOTH,则表示既不允许调用发送数据函数也不允许调用接收数
据函数
connect()函数
connect()函数实现连接服务器功能。
该函数声明如下:
int connect(SOCKET s, const struct cockaddr FAR * name, int namelen);
s:套接字
name:服务器地址
namelen:sockaddr结构的长度
当该函数调用成功时,函数返回0,调用失败时返回SOCKET_ERROR.
SOCKET s;//套接字
u_long ulServIP;//服务器IP
u_short usServPort;//服务器端口
int setVal;//返回值
//服务器地址
SOCKADDR_IN servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = htonl(ulServIP);
servAddr.sin_Port = htos(usServPort);
int nServLen = sizeof(servAddr);
//连接服务器
retVal = connect(s, (LPSOCKADDR)&servAddr, sizeof(servAddr));
if(SOCKET_ERROR == retVal)
{
//失败处理
}
开发过程:
Server:
WSAStartup()--socket()--bind()--listen()--accept()--recv()--closesocket--WSACleanup()
Client:
WSAStartup()--socket()--connect()--send()--closesocket()--WSACleanup()
相关文章推荐
- 【Linux网络编程笔记】TCP短连接产生大量TIME_WAIT导致无法对外建立新TCP连接的原因及解决方法—基础知识篇
- Java基础知识网络编程(TCP练习)
- 一、Linux网络编程-TCP/IP基础(一)ISO/OSI参考模型、TCP/IP四层模型、基本概念
- Java基础知识强化之网络编程笔记08:TCP之客户端键盘录入服务器控制台输出
- Linux下的socket编程实践(一) 网络基本知识以及 TCP/IP简述
- 网络编程的基础知识 TCP、UDP 学习日记
- Java基础知识强化之网络编程笔记14:TCP之多个客户端上传到一个服务器的思考(多线程改进)
- linux网络编程的一些基础知识--TCP协议相关
- 网络编程—套接字基础 & 基本TCP套接字编程-基本套接字函数
- 【Linux网络编程笔记】TCP短连接产生大量TIME_WAIT导致无法对外建立新TCP连接的原因及解决方法—基础知识篇
- C# 网络编程之套接字编程基础知识
- Java基础知识强化之网络编程笔记10:TCP之客户端读取文本文件服务器控制台输出
- Java基础知识强化之网络编程笔记11:TCP之TCP协议上传文本文件
- Java基础知识强化之网络编程笔记06:TCP之TCP协议发送数据 和 接收数据
- Java基础知识强化之网络编程笔记12:TCP之TCP协议上传文本文件并给出反馈
- Java基础知识强化之网络编程笔记09:TCP之客户端键盘录入服务器写到文本文件中
- Java基础知识强化之网络编程笔记13:TCP之TCP协议上传图片并给出反馈
- 网络编程(一)----基础知识、数据流套接字
- Windows sockets网络开发-基本TCP套接字编程