客户端 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地址可以 ...
随机推荐
- 时钟AnalogClock和DigitalClock
<AnalogClock android:layout_width="fill_parent" android:layout_height="fill_parent ...
- 面试贴:java异常小结
java的异常处理在面试中通常是个敏感的话题,这里我从整体框架方面稍微作一下我的小结. java的异常都继承Throwable这个类,也就是都可以抛出来的异常,在这个祖先类下,又分为如下子类: 1.E ...
- Vector和Arrarlist的异同;Hashtanle和HashMap的异同
Vector和ArrayList的异同 实现原理相同,功能相同,可以互用 主要区别: Vector线程安全,ArrayList重速度,轻安全,线程非安全. 长度需要增长时,Vector默认增长一倍,A ...
- Java测试(二)
一.选择题(每题2分,共40分) 1.下面哪个是Java语言中正确的标识符(C ) a) 3com b)import c)that d)this 2.下面哪个语句 ...
- charles 自动存储/auto_save
本文参考:charles 自动存储 自动保存工具 auto_save "自动保存"工具会在你设定的间隔后,自动保存并清除抓取到的内容.假设你设置了3分钟,则每隔三分钟会保存一次, ...
- 01.Django基础一之web框架的本质
一 web框架的本质及自定义web框架 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,基于请求做出响应,客户都先请求,服务端做出对应的响 ...
- HashMap源码分析(史上最详细的源码分析)
HashMap简介 HashMap是开发中使用频率最高的用于映射(键值对 key value)处理的数据结构,我们经常把hashMap数据结构叫做散列链表: ObjectI entry<Key, ...
- [DE] ML on Big data: MLlib
Pipeline的最终目的就是学会Spark MLlib,这里先瞧瞧做到心里有数:知道之后要学什么,怎么学. 首要问题 一.哪些机器学习算法可以并行实现? 四类算法:分类.回归.聚类.协同过滤 以及特 ...
- uboot学习之uboot启动流程简述
一.uboot启动分为了三个阶段BL0.BL1.BL2:BL0表示上电后运行ROM中固化的一段程序,其中ROM中的程序是厂家写进去的,所以具体功能可能根据厂家芯片而有所不同.功能如下: 初始化系统时钟 ...
- 代码审计之CSRF原理及修复
在平时的测试中,csrf也是比较容易发现的,主要就是看它对一个操作,有没有检测其时效性(这样表述可能不太准确),一般的防护方法就是添加token来进行校验,并及时对其进行失效处理. 以下所有代码都是我 ...