客户端 SOCKET 编程
建立客户端的 Socket:
客户端应用程序首先也是调用 WSAStartup() 函数来初始化 Winsock 的动态连接库,然后同样
调用 socket() 来建立一个 TCP 或 UDP Socket(相同协议的Socket 才能相遇,TCP 对 TCP,UDP 对 UDP)。
与服务器的 Socket 不同的是,客户端的 Socket 可以调用 bind() 函数,来指定 IP 地址及端口号 port。
但也可以不调用 bind() 函数。而由 Winsock 来自动设定 IP 地址及端口号 port。
发起连接申请:
当客户端程序需要连接服务器时,客户端程序的 Socket 调用 connect() 函数监听,与 name 所指定的计算机的特定
端口上的服务器端 Socket 进行连接。函数调用成功返回 0,否则返回 SOCKET_ERROR。
connect() 函数原型:
int connect(
SOCKET s, // 客户端流套接字
const struct sockaddr FAR *name, // 要连接的套接字的地址结构。
int namelen // 指明套接字的地址结构的长度。
);
函数示例:
//...
struct sockaddr_in name;
name.sin_family = FA_INET;
name.sin_port = htons();
name.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sSocket,(struct sockaddr *)&name,sizeof(name));
//...
inet_addr() 可以用来转化字符串,主要用来将一个十进制的数转化为二进制数,多用于 IPv4 的 ip 转化。
返回:若字符串有效则将字符串转换为32位二进制网络字节序的IPV4地址,否则为INADDR_NONE。
用 Socket 实现数据的传送:
服务器和客户端分别创建 Socket 并连接后,就开始数据的传递。网络编程数据传送涉及两大协议:TCP/IP 和 UDP 协议。
Stream (TCP) Socket:提供双向,可靠,有次序,不重复的资料传送。
Datagram (UDP) Socket:虽然提供双向的通信,但是没有 可靠,有次序,不重复的保证,
所以 UDP 传送数据可能收到无次序,重复的资料,甚至资料在传输过程中会泄露。
一般情况下 TCP Socket 的数据发送和接收是调用 send() 和 recv() 这两个函数来完成的,
而 UDP Socket 则是调用 sendto() 和 recvfrom() 这两个函数,这两个函数调用成功返回发送或接收的资料长度,
否则返回 SOCKET_ERROR。
send() 函数原型:
int send(
SOCKET s, // 指定发送端套接字描述符。
const char FAR *buf, // 指明一个存在应用程序要发送数据的缓冲区。
int len, // 指明实际要发送的数据的字节数。
int flags // 一般置 0。
);
不论是客户端还是服务端的应用程序都用 send() 函数向 TCP 连接的另一端发送数据。
客户端一般用 send() 函数 向服务器发送请求,而服务器通常用 send() 函数来向客户端程序发送应答。
对于同步 Socket 的 send() 函数执行流程,当调用它时,send 先比较待发送数据的长度(len)和套接字s 的发送端缓冲区大小。
如果 len 大于 s 的发送缓冲区的长度,该函数就返回 SOCKET_ERROR,发送失败。
反之,那么 send 先检查协议是否正在发送 s 发送缓冲区的数据。如果是,就等待协议把数据发送完,
如果协议还没有开始发送 s 的发送缓冲区的数据 或者 s 的发送缓冲区中没有数据,
那么send 就比较 s 的发送缓冲区的剩余空间和 len 的大小。如果 len 大于剩余空间大小,
send 就一直等待协议把 s 的发送缓冲区中的数据发送完,反之,send 就仅仅把 buf 中的数据复制到剩余空间里
注意并不是 send 把 s 的发送缓冲区中的数据传到连接的另一端的,而是协议传的,
send 仅仅是把 buf 中的数据复制到 s 的发送缓冲区的剩余空间里)。
如果 send() 函数复制数据成功,就返回实际复制的字节数,否则,就返回 SOCKET_ERROR。
如果 send() 函数在等待协议传送数据时网络断开,也返回 SOCKET_ERROR。
send() 函数把 buf 中的数据成功复制到 s 的发送缓冲区的剩余空间中后它就返回了,但是此时这些数据
并不一定马上就传到连接的另一端。
如果协议在后续的传递过程中出现网络错误的话,那么下一个 socket 函数就会返回 SOCKET_ERROER。
提示:
每一个除 send 外的 socket 函数在执行最开始总要等待套接字的发送缓冲区中的数据被协议传送完毕才能继续,
如果出现网络错误,那么该 socket 函数就返回 SOCKET_ERROR。
recv() 函数原型:
int recv(
SOCKET s, // 指定接收端套接字描述符。
char FAR *buf, // 指明一个缓冲区,该缓冲区用来存放 recv() 函数接收到的数据。
int len, // 指明 buf 的长度。
int flags // 一般置 0。
);
不论客户端还是服务器端应用程序都用 recv() 函数从 TCP/IP 连接的另一端接收数据。
对于同步 Socket 的 recv() 函数执行流程,当调用它时,recv() 函数先等待 s 的发送缓冲区中的数据传输完毕。
如果协议在传送 s 的发送缓冲区中的数据时出现网络错误的话,那么 recv() 函数就会返回 SOCKET_ERROER。
如果 s 的发送缓冲区中没有数据 或者数据被协议接收完毕后,recv() 函数 会先检查套接字 s 的接收缓冲区,
如果 s 的接收缓冲区中没有数据或协议正在接收数据,那么 recv() 函数就会一直等待,直到数据接收完毕。
当协议把数据接收完毕,recv() 函数就把 s 的接收缓冲区中的数据拷贝到 buf 中。
(注意协议接收到的数据可能大于 buf 的长度,所以在这种情况下需要调用几次 recv() 函数才能把 s
接收缓冲区的数据拷贝完。recv() 函数仅仅是拷贝数据,真正的接收数据是协议完成的。)
recv() 函数返回其实是拷贝的字节数,如果 recv() 函数在拷贝时出错,那么它返回 SOCKET_ERROR。
如果 recv() 函数在等待协议接收数据时网络中断,那么它返回 0。
sendto() 函数原型:
int sendto(
SOCKET s, // 指定发送端套接字描述符。
const char *buf, // 指明一个存放应用程序要发送数据的缓冲区。
int len, // 指明实际要发送的数据字节数。
int flags, // 一般置 0。
const struct sockaddr* to, // 为指向目的地址的指针。(表示目的机的 ip 和 port).
int tolen // 为 to 的长度。(一般赋值为 sizeof(sturct sockaddr).
);
recvfrom() 函数原型:
int recvfrom(
SOCKET s, // 指定接收端的套接字描述符。
char *buf, // 指明一个缓冲区,该缓冲区用来存放 recvfrom() 函数接收到的数据。
int len, // 指明 buf 的长度。
int flags, // 一般置 0.
struct sockaddr *from, // 为数据包的来源地址。
int *fromlen // 数据包的长度。
);
#include<stdio.h>
#include<winsock.h>
#pragma comment(lib,"ws2_32")
#define PORT 1234
int main(void)
{
SOCKET sockfd;
WSADATA ws;
char Buffer[MAX_PATH];
struct sockaddr_in their_addr; if(WSAStartup(MAKEWORD(, ), &ws) != 0)
{
exit(0);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
exit(0);
} their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(PORT);
their_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if (connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
closesocket(sockfd);
exit(0);
}
printf("input your msg:\n");
gets_s(Buffer);
send(sockfd, Buffer, MAX_PATH, );
closesocket(sockfd);
WSACleanup();
getchar();
return ;
}
客户端 SOCKET 编程的更多相关文章
- socket编程学习step1
socket学习参考链接,赞一个:http://blog.csdn.net/hguisu/article/details/7445768 sockets(套接字)编程有三种,流式套接字(SOCK_ST ...
- socket编程中客户端常用函数
1 常用函数 1.1 connect() int connect(int sockfd, const struct sockaddr *servaddr, socklen_taddrlen); 客 ...
- Windows Socket 编程_单个服务器对多个客户端简单通讯
单个服务器对多个客户端程序: 一.简要说明 二.查看效果 三.编写思路 四.程序源代码 五.存在问题 一.简要说明: 程序名为:TcpSocketOneServerToMulClient 程序功能:实 ...
- 你得学会并且学得会的Socket编程基础知识(续)——Silverlight客户端
本文将在这个案例的基础上,加入一个特殊场景,利用Silverlight来实现客户端.有的朋友可能会说,其实是一样的吧.请不要急于下结论,有用过Silverlight的朋友都有这种体会,很多在标准.NE ...
- Python Socket 网络编程 (客户端的编程)
Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ ...
- 利用socket编程在ESP32上搭建一个TCP客户端
通过之前http://www.cnblogs.com/noticeable/p/7636582.html中对socket的编程,已经可以知道如何通过socket编程搭建服务器和客户端了,现在,就在ES ...
- socket编程:客户端与服务器间的连接以及各函数的用法
在认真的看UNP之前,一直被socket编程说的云里雾里,今天我要让大家从整天上认识socket编程,让我们知道socket编程的整个流程和各个函数的用法.这样:我们在写一些简单的socket编程时就 ...
- java 网络编程基础 TCP/IP协议:服务端ServerSocket;客户端Socket; 采用多线程方式处理网络请求
1.Java中客户端和服务器端通信的简单实例 Java中能接收其他通信实体连接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一 ...
- java socket编程(li)
一.网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输.在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以 ...
随机推荐
- Unity3D_04_GameObject,Component,Time,Input,Physics
Unity3D是一个Component-Based的游戏引擎,并且为GamePlay Programmer提供了很多游戏性层上的支持. 1.可以在图形界面上设计动画状态转换的Animator. 2.可 ...
- selenium IDE的断言与验证
断言 验证应用程序的状态是否同所期望的一致.常见的断言包括验证页面内容,如标题是否为X或当前位置是否正确等等 断言被用于4种模式+5种手段: Assert Assert断言失败时,该测试将终止 ver ...
- pip版本降级
使用命令:python -m pip install pip==8.1.1 其中, -m参数的解释 run library module as a script (terminates option ...
- SpringCloud(五)Zuul网关与分布式配置中心
在 Spring Cloud 微服务系统中,一种常见的负载均衡方式是,客户端的请求首先经过负载均衡(Ngnix),再到达服务网关(Zuul 集群),然后再到具体的服务.服务统一注册到高可用的服务注册中 ...
- 01:***VideoToolbox硬编码H.264
最近接触了一些视频流H264的编解码知识,之前项目使用的是FFMpeg多媒体库,利用CPU做视频的编码和解码,俗称为软编软解.该方法比较通用,但是占用CPU资源,编解码效率不高.一般系统都会提供GPU ...
- .NET Core 获取请求类容(body)
.Net Core 对于body多次读取,开放了一个参数EnableRewind(),该参数在第一次读取body之前开启,之后body信息可以多次读取:core时代取消了之前的stream.posit ...
- linux语句速查
一.netstat -a或--all:显示所有连线中的Socket -A<网络类型>或--<网络类型>:列出该网络类型连线中的相关地址 -c或--continuous:持续列出 ...
- 译 .NET Core 3.0 发布
原文:<Announcing .NET Core 3.0> 宣布.NET Core 3.0 发布 很高兴宣布.NET Core 3.0的发布.它包括许多改进,包括添加Windows窗体和W ...
- BUG 的生命周期
BUG 的生命周期 Bug-->软件程序的漏洞或缺陷 Bug 的类型:代码错误.设计缺陷.界面优化.性能问题.配置相关.安装部署.安全相关.标准规划.测试脚本....其他(功能类.界面类.性能类 ...
- Kilani and the Game-吉拉尼的游戏 CodeForce#1105d 模拟 搜索
题目链接:Kilani and the Game 题目原文 Kilani is playing a game with his friends. This game can be represente ...