TCP:

server

#include "stdafx.h"
#include<iostream>
#define BUF_SZIE 64
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib") using namespace std; int main(int argc, char* argv[])
{
WSADATA wsd; //WSADATA变量
SOCKET sServer; //服务器套接字
SOCKET sClient; //客户端套接字
SOCKADDR_IN addrServ;; //服务器地址 SOCKADDR_IN只是SOCKADDR在TCP/IP协议下的一个特例
char buf[BUF_SZIE]; //接收数据缓冲区
int retVal; //返回值 //初始化套结字动态库,加载Windows Socket动态库DLL
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)//wsd返回被加载动态库的有关信息
{
cout<<"WSAStartup failed!\n";
return 1;
}
if(LOBYTE(wsd.wVersion)!=2||HIBYTE(wsd.wHighVersion)!=2)
{
WSACleanup();//释放套接字资源;
return -1;
}
//创建套接字
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == sServer)
{
cout<<"socket failed!\n";
WSACleanup();//释放套接字资源;
return -1;
} //服务器套接字地址
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(4999); //从主机字节顺序转换为网络字节顺序 host to net long/short 相关函数htonl ntohl() ntohs()
addrServ.sin_addr.s_addr = INADDR_ANY;
//绑定套接字
retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
if(SOCKET_ERROR == retVal)
{
cout<<"bind failed!\n";
closesocket(sServer); //关闭套接字
WSACleanup(); //释放套接字资源;
return -1;
} //开始监听
retVal = listen(sServer, 1);
if(SOCKET_ERROR == retVal)
{
cout<<"listen failed!\n";
closesocket(sServer); //关闭套接字
WSACleanup(); //释放套接字资源;
return -1;
} //接受客户端请求
sockaddr_in addrClient;
int addrClientlen = sizeof(addrClient);
sClient = accept(sServer,(sockaddr FAR*)&addrClient, &addrClientlen);
if(INVALID_SOCKET == sClient)
{
cout<<"accept failed!\n";
closesocket(sServer); //关闭套接字
WSACleanup(); //释放套接字资源;
return -1;
} //接收客户端数据
ZeroMemory(buf, BUF_SZIE);
retVal = recv(sClient, buf, BUF_SZIE, 0);
if (SOCKET_ERROR == retVal)
{
cout<<"recv failed!\n";
closesocket(sServer); //关闭套接字
closesocket(sClient); //关闭套接字
WSACleanup(); //释放套接字资源;
return -1;
} cout<< buf; //输出"MyTCP" //退出
closesocket(sServer); //关闭套接字,同时关闭网络连接
closesocket(sClient); //关闭套接字
WSACleanup(); //释放套接字资源; system("pause");
return 0;
}

client

#include "stdafx.h"
#include<iostream>
#define BUF_SZIE 64
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib") using namespace std; int main(int argc, char* argv[])
{ WSADATA wsd; //WSADATA变量
SOCKET sHost; //服务器套接字
SOCKADDR_IN servAddr; //服务器地址
char buf[BUF_SZIE]; //接收数据缓冲区
int retVal; //返回值 //初始化套结字动态库
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
cout<<"WSAStartup failed!\n";
return -1;
} //创建套接字
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == sHost)
{
cout<<"socket failed!\n";
WSACleanup();//释放套接字资源
return -1;
} //设置服务器地址
servAddr.sin_family =AF_INET;
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //实现网络地址和“.”间隔字符串地址之间的转换
//char* pAddr=inet_ntoa(*(in_addr*)(&servAddr.sin_addr.s_addr));
servAddr.sin_port = htons((short)4999);
int nServAddlen = sizeof(servAddr); //连接服务器
retVal=connect(sHost,(LPSOCKADDR)&servAddr, sizeof(servAddr));
if(SOCKET_ERROR == retVal)
{
cout<<"connect failed!\n";
closesocket(sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -1;
} //向服务器发送数据
ZeroMemory(buf, BUF_SZIE);
strcpy(buf, "MyTCP");
retVal = send(sHost, buf, strlen(buf), 0);
if (SOCKET_ERROR == retVal)
{
cout<<"send failed!\n";
closesocket(sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -1;
} //退出
closesocket(sHost); //关闭套接字
WSACleanup(); //释放套接字资源 system("pause");
return 0;
}

UDP:

server

#include "stdafx.h"
#include<iostream>
#define BUF_SZIE 64
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib") using namespace std; int main(int argc, char* argv[])
{ WSADATA wsd; //WSADATA变量
SOCKET s; //套接字
SOCKADDR_IN servAddr; //服务器地址
char buf[BUF_SZIE]; //接收数据缓冲区 //初始化套结字动态库
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
cout<<"WSAStartup failed!\n";
return 1;
} //创建套接字
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
{
cout<<"socket() failed; %d\n"<<WSAGetLastError();
WSACleanup();//释放套接字资源
return 1;
} int nErrCode; //返回值
int nBufLen; //接收数据缓冲区大小
int nOptlen = sizeof(nBufLen);
//获取接收数据缓冲区大小
nErrCode = getsockopt(s, SOL_SOCKET, SO_RCVBUF,(char*)&nBufLen, &nOptlen);
if (SOCKET_ERROR == nErrCode)
{
//处理失败
} //设置接收数据缓冲区为原来的10倍
nBufLen *= 10;
nErrCode = setsockopt(s, SOL_SOCKET, SO_RCVBUF,(char*)&nBufLen, nOptlen);
if (SOCKET_ERROR == nErrCode)
{
//失败处理
} //检查设置系统接收数据缓冲区是否成功
int uiNewRcvBuf;
getsockopt(s, SOL_SOCKET, SO_RCVBUF,(char*)&uiNewRcvBuf, &nOptlen);
if (SOCKET_ERROR == nErrCode || uiNewRcvBuf != nBufLen)
{
//失败处理
} //服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons((short)5000); //端口
servAddr.sin_addr.s_addr = htonl(INADDR_ANY); //IP //绑定
if (bind(s, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
cout<<"bind() failed: %d\n"<<WSAGetLastError();
closesocket(s); //关闭套接字
WSACleanup(); //释放套接字资源
return 1;
} //接收数据
SOCKADDR_IN clientAddr;
int nClientLen = sizeof(clientAddr);
ZeroMemory(buf, BUF_SZIE);
if(recvfrom(s, buf, BUF_SZIE, 0, (SOCKADDR*)&clientAddr, &nClientLen) == SOCKET_ERROR)
{
cout<<"recvfrom() failed: %d\n"<<WSAGetLastError();
closesocket(s); //关闭套接字
WSACleanup(); //释放套接字资源
return 1;
} cout<<buf;//输出"MyUDP" closesocket(s); //关闭套接字
WSACleanup(); //释放套接字资源 system("pause");
return 0;
}

client

#include "stdafx.h"
#include<iostream>
#define BUF_SZIE 64
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib") using namespace std; int main(int argc, char* argv[])
{ WSADATA wsd; //WSADATA变量
SOCKET s; //套接字
SOCKADDR_IN servAddr; //服务器地址
char buf[BUF_SZIE]; //发送数据缓冲区 //初始化套结字动态库
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
cout<<"WSAStartup failed!\n";
return 1;
} //创建套接字
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
{
cout<<"socket() failed; %d\n"<<WSAGetLastError();
WSACleanup();//释放套接字资源
return 1;
} //赋值“MyUDP”
ZeroMemory(buf, BUF_SZIE);
strcpy(buf, "MyUDP"); //服务器地址
servAddr.sin_family =AF_INET;
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servAddr.sin_port = htons((short)5000);
int nServAddlen = sizeof(servAddr); //发送数据
if(sendto(s, buf, BUF_SZIE, 0, (SOCKADDR*)&servAddr, nServAddlen) == SOCKET_ERROR)
{
cout<<"recvfrom() failed: %d\n"<<WSAGetLastError();
closesocket(s); //关闭套接字
WSACleanup(); //释放套接字资源
return 1;
} closesocket(s); //关闭套接字
WSACleanup(); //释放套接字资源 system("pause");
return 0;
}

套接字选项

创建套接字后,通过套接字选项对其各种属性进行设置,便可对套接字的行为产生影响。

getsockopt()函数用于获取套接字选项信息,声明如下

int getsockopt(SOCKET s,int level,int optname,char FAR* optval,int FAR* optlen);

s:      套接字

level:  选项级别,有SOL_SOCKET和IPPROTO_TCP两个级别

optname:套接字选项名称

optval: 接收数据缓冲区,该参数返回套接字选项名称对应的值。

optlen: 缓冲区大小

setsockopt()函数用于设置套接字选项,声明如下

int setsockopt(SOCKET s,int level,int optname, const char FAR* optval,int FAR* optlen);

s:      套接字

level:  选项级别,有SOL_SOCKET和IPPROTO_TCP两个级别

optname:套接字选项名称

optval: 该参数用于设置套接字选项的值。

optlen: 缓冲区大小

SOL_SOCKET选项级别

Socket选项

类型

缺省值

说明

SO_ACCEPTCON

BOOL

FALSE

套接口正在监听

SO_BROADCAST

BOOL

FALSE

允许套接口传送广播信息。

SO_DEBUG

BOOL

FALSE

记录调试信息。

SO_DONTLINGER

BOOL

FALSE

不要因为数据未发送就阻塞关闭操作。

SO_DONTROUTE

BOOL

FALSE

禁止选径;直接传送。

SO_ERROR

int

0

获取错误状态并清除。

SO_KEEPALIVE 

BOOL

FALSE

发送“保持活动”包。

SO_LINGER

struct linger FAR*

0

关闭时有未发送数据,则逗留。

SO_OOBINLINE

BOOL

FALSE

在常规数据流中接收带外数据。

SO_RCVBUF

int

 

设置或者获取接收缓冲区的大小。

SO_REUSEADDR

BOOL

FALSE

允许套接口和一个已在使用中的地址捆绑

SO_SNDBUF

int

 

设置或者获取发送缓冲区的大小。

SO_TYPE

int

 

返回套接字类型,如SOCK_DGRAM,SOCK_STREAM。

SO_SNDTIMEO

Int

 

设置或获取套接字在发送数据的超时时间。

SO_RCVTIMEO

int

 

设置或获取套接字在接收数据的超时时间。

TCP_NODELAY

BOOL

FALSE

禁止发送合并的Nagle算法

详细用法

1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:

BOOL bReuseaddr=TRUE;
setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));

2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历TIME_WAIT的过程:

BOOL bDontLinger = FALSE;
setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL));

3.在send(),recv()过程中有时由于网络状况等原因,发收不能预期进行,而设置收发时限:

int nNetTimeout=1000;//1秒
//发送时限
setsockopt(socket,SOL_S0CKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
//接收时限
setsockopt(socket,SOL_S0CKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));

4.在send()的时候,返回的是实际发送出去的字节(同步)或发送到socket缓冲区的字节

(异步);系统默认的状态发送和接收一次为8688字节(约为8.5K);在实际的过程中发送数据

和接收数据量比较大,可以设置socket缓冲区,而避免了send(),recv()不断的循环收发:

// 接收缓冲区
int nRecvBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
//发送缓冲区
int nSendBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));

5. 如果在发送数据的时,希望不经历由系统缓冲区到socket缓冲区的拷贝而影响程序的性能:

int nZero=0;
setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero));

6.同上在recv()完成上述功能(默认情况是将socket缓冲区的内容拷贝到系统缓冲区):

int nZero=0;
setsockopt(socket,SOL_S0CKET,SO_RCVBUF,(char *)&nZero,sizeof(int));

7.一般在发送UDP数据报的时候,希望该socket发送的数据具有广播特性:

BOOL bBroadcast=TRUE;
setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(BOOL));

8.在client连接服务器过程中,如果处于非阻塞模式下的socket在connect()的过程中可以设置connect()延时,

直到accpet()被呼叫(本函数设置只有在非阻塞的过程中有显著的作用,在阻塞的函数调用中作用不大)

BOOL bConditionalAccept=TRUE;
setsockopt(s,SOL_SOCKET,SO_CONDITIONAL_ACCEPT,(const char*)&bConditionalAccept,sizeof(BOOL));

9.如果在发送数据的过程中(send()没有完成,还有数据没发送)而调用了closesocket(),

以前我们一般采取的措施是"从容关闭"shutdown(s,SD_BOTH),但是数据是肯定丢失了,

如何设置让程序满足具体应用的要求(即让没发完的数据发送出去后在关闭socket)

struct linger {
u_short l_onoff;
u_short l_linger;
};
linger m_sLinger;
m_sLinger.l_onoff=1;//(在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)
// 如果m_sLinger.l_onoff=0;则功能和2.)作用相同;
m_sLinger.l_linger=5;//(容许逗留的时间为5秒)
setsockopt(s,SOL_SOCKET,SO_LINGER,(const char*)&m_sLinger,sizeof(linger));



最简单的TCP、UDP案例及各函数的详细解释的更多相关文章

  1. 最简单的Tcp Udp的例子

    //1.WinSock包含2个主要的版本,即WinSock1和WinSock2.前者需要包含头文件WinSock.h和库文件wsock32.lib,后者需要包含头文件WinSock2.h和库文件ws2 ...

  2. python tcp,udp简单使用

    import socket host = '127.0.0.1' port = 9999 #创建一个tcp socket套接字 tcp_server = socket.socket(socket.AF ...

  3. 网络基础--简单理解什么是DNS? TCP? UDP? Http? Socket?

    什么是IP 协议?  协议就是为了实现网络通信而创建的一系列规范.  通常我们的网络模型从上到下共分为4层: 应用层, 传输层, 网络层 和数据链路层. IP协议属于网络层协议,它精确定义了网络通信中 ...

  4. 为什么基于TCP UDP服务的一些简单服务端口号都是奇数

    TCP是有NCP(网络控制协议)派生出来的,NCP是单工的,通信需要两个链接,所以会预留奇偶端口号.当TCP/UDP成为传输层协议,每个程序只是用一个端口号,且使用奇端口号.

  5. [转][linux]简单的linux下的tcp/udp

    转自:https://blog.csdn.net/cabing2005/article/details/53068880 详细函数以及参数解释请看原链接. windows下的tcp/udp参考:htt ...

  6. Nginx基于TCP/UDP端口的四层负载均衡(stream模块)配置梳理

    通过我们会用Nginx的upstream做基于http/https端口的7层负载均衡,由于Nginx老版本不支持tcp协议,所以基于tcp/udp端口的四层负载均衡一般用LVS或Haproxy来做.至 ...

  7. TCP UDP Socket 即时通讯 API 示例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  8. 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.1

    HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...

  9. TODO:Golang语言TCP/UDP协议重用地址端口

    TODO:Golang语言TCP/UDP协议重用地址端口 这是一个简单的包来解决重用地址的问题. go net包(据我所知)不允许设置套接字选项. 这在尝试进行TCP NAT时尤其成问题,其需要在同一 ...

随机推荐

  1. js文件引入

    js文件内引用js文件使用 document.write("<script language='javascript' src='scripts/lang/chs.js'>< ...

  2. 表单提交时编码类型enctype详解

    很早以前,当还没有前端这个概念的时候,我在写表单提交完全不去理会表单数据的编码,在action属性里写好目标URL,剩下的啊交给浏览器吧~但是现在,更多时候我们都采用Ajax方式提交数据,这种原始的方 ...

  3. OC基础:block.字面量 分类: ios学习 OC 2015-06-22 19:08 155人阅读 评论(0) 收藏

    block 块语法,可以用block去保存一段代码,或者封装一段代码. block 实际是由c语言实现的,执行效率很高. block 实际借鉴了函数指针的语法. block,在多线程.异步任务,集合遍 ...

  4. 解决tensorflow的"Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA Using TensorFlow backend."警告问题

    问题描述 程序开始运行的时候报出警告:I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructio ...

  5. 第二篇 makefile的基本结构

    makefile用于定义并描述源文件之间的依赖关系,用于说明如何编译各个源文件并生成最终的可执行文件,规则是makefile中的基本组成部分. 一个最基本的依赖规则如下所示: targets代表这个规 ...

  6. OK335xS-Android pack-ubi-256M.sh hacking

    #/******************************************************************************* # * OK335xS-Androi ...

  7. IIS7中Ajax.AjaxMethod无效的原因及解决方法

    使用Ajax.AjaxMethod方法在asp.net的服务器下一切正常,用iis的时候,js中总是cs类找不到,具体的解决方法如下,遇到类似情况的朋友可以参考下 最近做用Ajax.AjaxMetho ...

  8. ACM常用算法

    数据结构 栈,队列,链表 哈希表,哈希数组 堆,优先队列 双端队列 可并堆 左偏堆 二叉查找树 Treap 伸展树 并查集 集合计数问题 二分图的识别 平衡二叉树 二叉排序树 线段树 一维线段树 二维 ...

  9. socat 广播以及多播

    官方文档有一个关于组播,多播的例子挺不错,记录下 多播客户端以及服务器 注意地址修改为自己的网络 server socat UDP4-RECVFROM:6666,ip-add-membership=2 ...

  10. Entity Framework常用的查询方式

    Entity Framework支持的查询方式有三种 LINQ to Entities Entity SQL Native SQL [LINQ to Entities] LINQ(语言集成查询)是从V ...