TCP/UDP网络编程的基础知识与基本示例(windows和Linux)
一、TCP编程的一般步骤
服务器端:
1、创建一个socket,用函数socket()
2、绑定IP地址、端口等信息到socket上,用函数bind()
3、开启监听,用函数listen()
4、接收客户端上来的连接,用函数accept()
5、收发数据,用函数send()和recv(),或者read()和write()
6、关闭网络连接
7、关闭监听
客户端:
1、创建一个socket,用函数socket()
2、设置要连接的对方IP地址和端口等属性
3、连接服务器,用函数connect()
4、收发数据,用函数send()和recv(),或者read()和write()
5、关闭网络连接
以下是TCP通信的时序图:

二、UDP编程的一般步骤
服务器:
1、创建一个socket,用函数socket()
2、绑定IP地址、端口等信息到socket上,用函数bind()
3、循环接收数据,用函数recvfrom()
4、关闭网络连接
客户端:
1、创建一个socket,用函数socket()
2、设置对方的IP地址、端口等属性
3、发送数据,用函数sendto()
4、关闭网络连接
以下是UDP通信的时序图:

三、Windows socket和Linux socket编程的区别
1、头文件
Windows下winsocket.h/winsocket2.h
Winsocket2.0需要ws2_32.lib和ws2_32.dll
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()
9、后续用到会再补充!!!
四、网络编程示例
1、Windows下TCP编程
服务器:
#include "stdafx.h"
#include <WinSock2.h>
#include <iostream>
using namespace std;
#include <stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
WORD wVersionRequested = MAKEWORD(2,2);//确定最高可使用的socket版本
WSADATA wsaData;//用来存储winsocket初始化信息
int err = WSAStartup(wVersionRequested, &wsaData);//初始化使用winsocket dll
if (err != 0)
{
cout<<"WSAStartup failed!"<<endl;
}
//步骤一:创建服务器socket
//第一个参数选择协议族,第二个选择数据流类型,第三个选择协议类型
SOCKET socketSrv = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (socketSrv == INVALID_SOCKET)
{
cout<<"Create socket failed"<<endl;
}
//步骤二:绑定端口、IP信息到socket上
SOCKADDR_IN addrSrv; //这个结构用来存储本地端和远程端用来连接socket的信息
//使用系统指定的IP地址。htonl将一个无符号长整形主机字节序转化为一个TCP/IP网络字节序(大端)
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(8888);//htons将一个无符号短整型端口主机字节序转化为一个TCP/IP网络字节序(大端)
if (int n = bind(socketSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)))
{
cout<<"bind server socket failed"<<endl;
}
//步骤三:监听
if (listen(socketSrv,SOMAXCONN))//第二个参数为可接受的最大连接请求数
{
cout<<"listen failed"<<endl;
}
//步骤四:接收客户端连接
SOCKADDR_IN addrClient;//用来存放客户连接信息
int nLen = sizeof(SOCKADDR);
char buf1[255] = "";//存放连接的客户IP和端口信息字符串
char buf2[255] = "";//接收和发送缓冲数据
char bufRecv[255] = "";
//这个nlen没有设初值也会出错的哦
SOCKET socketCon = accept(socketSrv,(SOCKADDR*)&addrClient,&nLen);//后面改成多线程后就能连接多人对话
while (true)
{
//inet_ntoa将IPv4网络地址转换成标准的点治式字符串(例如:192.168.1.1)
//ntohs将无符号短整型网络字节序转换为无符号短整型主机字节序,与上面的htons相反
sprintf(buf1,"***IP:%s PORT:%d #\n",inet_ntoa(addrClient.sin_addr),ntohs(addrClient.sin_port));
//步骤五:接收和传送数据
int nBytesRecv = recv(socketCon,bufRecv,sizeof(bufRecv),0);
if (strcmp(bufRecv,"exit") == 0)
{
//closesocket(socketCon);
break;
}
strcat(buf1,bufRecv);
cout<<buf1<<endl;
cout<<"***YOU#:"<<endl;
//cin>>buf2;
cin.getline(buf2,sizeof(buf2));
int nBytesSent = send(socketCon,buf2,sizeof(buf1),0);
}
//步骤六:关闭连接
closesocket(socketCon);
closesocket(socketSrv);
WSACleanup();//终止使用winsocket dll
return 0;
}
客户端:
#include "stdafx.h"
#include <WinSock2.h>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
WORD wVersionRequested = MAKEWORD(2,2);
WSADATA wsaData;
if (WSAStartup(wVersionRequested,&wsaData))
{
cout<<"WSAStartup failed"<<endl;
}
//步骤一:创建socket
SOCKET socktClient = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
//步骤二:设置要连接的对方的IP、端口等信息
SOCKADDR_IN addrClient;
//inet_addr将一个点制式IP字符串转换为适合IN_ADDR结构的形式
addrClient.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrClient.sin_family = AF_INET;
addrClient.sin_port = htons(8888);
//步骤三:连接服务器
if (connect(socktClient,(SOCKADDR*)&addrClient,sizeof(SOCKADDR)))
{
cout<<"connect failed"<<endl;
}
char buf[255] = "";
while (true)
{
//步骤四:收发数据
cout<<"***YOU#"<<endl;
//cin>>buf;
cin.getline(buf,sizeof(buf));
if (strcmp(buf,"exit") == 0)
{
break;
}
int nBytesSent = send(socktClient,buf,sizeof(buf),0);
int nBytesRecv = recv(socktClient,buf,sizeof(buf),0);
cout<<"***Server#"<<endl;
cout<<buf<<endl;
}
//步骤五:关闭连接
closesocket(socktClient);
return 0;
}
2、WIndows下UDP编程
服务器:
#include "stdafx.h"
#include <WinSock2.h>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
WORD wVersionRequested = MAKEWORD(2,2);
WSADATA wsaData;
WSAStartup(wVersionRequested,&wsaData);
//步骤一:创建socket
SOCKET socketSrv = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);//这里换成了非面向连接的数据报模式
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(8000);
//步骤二:绑定端口、IP等信息到socket上
if (bind(socketSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)))
{
cout<<"bind failed"<<endl;
}
char buf[255] = "";
while (true)
{
SOCKADDR_IN addrClient;//用来存放客户连接信息
int nLen = sizeof(SOCKADDR);
//步骤三:接收数据
int nBytesRecv = recvfrom(socketSrv,buf,sizeof(buf),0,(SOCKADDR*)&addrClient,&nLen);//这里不用变量存储会报错
if (strcmp(buf,"exit") == 0)
{
//closesocket(addrClient);
continue;
}
cout<<"Client#"<<endl;
cout<<buf<<endl;
}
//步骤四:关闭网络连
closesocket(socketSrv);
WSACleanup();
return 0;
}
客户端:
#include "stdafx.h"
#include <WinSock2.h>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
WORD wVersionRequested = MAKEWORD(2,2);
WSADATA wsaData;
WSAStartup(wVersionRequested,&wsaData);
//步骤一:创建socket
SOCKET socketClient = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);//这里换成了非面向连接的数据报模式
//步骤二:设置要数据接收者的地址信息
SOCKADDR_IN addrTo;
addrTo.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrTo.sin_family = AF_INET;
addrTo.sin_port = htons(8000);
char buf[255] = "";
while (true)
{
cout<<"YOU#"<<endl;
cin.getline(buf,sizeof(buf));
if (strcmp(buf,"exit") == 0)
{
break;
}
//步骤三:发送数据
int nBytesSent = sendto(socketClient, buf,strlen(buf)+1,0,(SOCKADDR*)&addrTo,sizeof(SOCKADDR));
}
//步骤四:关闭网络连
closesocket(socketClient);
WSACleanup();
return 0;
}
3、Linux下TCP编程
服务器:
客户端:
2、Linux下UDP编程
服务器:
客户端:
TCP/UDP网络编程的基础知识与基本示例(windows和Linux)的更多相关文章
- python六十七课——网络编程(基础知识了解)
网络编程: 什么是网络编程? 网络:它是一种隐形的媒介:可以将多台计算机使用(将它们连接到一起) 网络编程:将多台计算机之间可以相互通信了(做数据交互) 一旦涉及到网络编程,划分为两个方向存在,一方我 ...
- java第九节 网络编程的基础知识
/** * * 网络编程的基础知识 * 网络协议与TCP/IP * IP地址和Port(端口号) * 本地回路的IP地址:127.0.0.1 * 端口号的范围为0-65535之间,0-1023之间的端 ...
- 01网络编程(基础知识+OSI七层协议+TCP与UDP)
目录 01 网络编程 一.软件开发架构 1.1 CS架构 1.2 BS架构 二.网络理论前戏 2.1 简介 2.2 常见硬件 三.OSI七层协议(五层) 3.1 七层协议 3.2 五层协议 3.3 知 ...
- TCP/IP网络编程技术基础
零零碎碎记下点→ 不对的欢迎大家批评纠正→ 以免本人及偶尔看到此博客的人继续迷途未返→ >>>>>基础知识→ 1→TCP/IP英文名:Tranmission Contro ...
- 自测之Lesson15:TCP&UDP网络编程
题目:编写一个TCP通信的程序. 实现代码: #include <stdio.h> #include <sys/socket.h> #include <unistd.h& ...
- 《TCP/IP网络编程》
<TCP/IP网络编程> 基本信息 作者: (韩)尹圣雨 译者: 金国哲 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9787115358851 上架时间:2014-6- ...
- 【RL-TCPnet网络教程】第16章 UDP用户数据报协议基础知识
第16章 UDP用户数据报协议基础知识 本章节为大家讲解UDP(User Datagram Protocol,用户数据报协议),需要大家对UDP有个基础的认识,方便后面章节UDP实战操作. ...
- 三十天学不会TCP,UDP/IP编程--MAC地址和数据链路层
这篇文章主要是来做(da)推(guang)介(gao)的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,后面会 ...
- python网络编程——socket基础篇
python的网络编程比c语言简单许多, 封装许多底层的实现细节, 方便程序员使用的同时, 也使程序员比较难了解一些底层的东西. 1 TCP/IP 要想理解socket,首先得熟悉一下TCP/IP协议 ...
随机推荐
- Altium Designer 生成 Mach3 G代码的程序
Altium Designer做PCB设计,还是很方便的,最近头脑发热,在网上买了一套CNC机床,用来做钻孔用,但是翻来翻去,基本上所有的软件都是铣削功能,而且很多软件很复杂.翻了好几天,发现没有什么 ...
- a标签加绝对定位在图片上面,a的链接和块状属性block失效,而且是所有IE版本都失效的
谷歌和火狐浏览器下测试是正常的,IE下鼠标移过logo是没有超链接的提示的 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitio ...
- CSS优先级、引入方式、Hack
优先级 important > 内联(1,0,0,0) > id(1,0,0) > class(1,0) > element(1) > *通配符 css引入方式 方式一: ...
- PHP第三节笔记
●为什么要安装web服务器,和怎么样去了解发送和接受到什么? 1.因为我们的浏览器要取数据,数据是从服务器取出来的. 2.我们可以通过httpwatch工具来获取发送和接收的数据,有利于我们了解的更加 ...
- 使用 OpenWrt Image Generator 为 WR703N 路由器定制固件
标题:使用 OpenWrt Image Generator 为 WR703N 路由器定制固件 之前试着自己编译固件,编译是成功了,但是在后期安装官方仓库的ipk时出现问题,因为自己编译的固件和官方固件 ...
- 观《Terminal》之感
读书笔记系列链接地址http://www.cnblogs.com/shoufengwei/p/5714661.html. 经人推荐,用了几天时间欣赏了这部斯皮尔伯格导演的电影<Te ...
- VirtualBox 修改UUID实现虚拟硬盘复制
最近用VirtualBox创建虚拟机,复制了一个虚拟硬盘之后,直接添加到列表,发现无法使用....提示为UUID已经被使用. 查找了一下解决方法:一般的介绍说操作方法为: 在命令行中,打开Virtua ...
- if条件语句练习(相亲)
public class a { public static void main(String[] arg){ //F是房子,Q是钱,N是能力,等于0说明没有,等于1说明有: 有一项具备则可以嫁,都不 ...
- 第10讲- UI线程阻塞及其优化
第10讲UI线程阻塞及其优化 .UI 阻塞demo (首先在activity_main.xml中放置两个button,分别命名为button1,button2) //首先设置一个button1用来进行 ...
- 面试时如何优雅的谈论OC
在面试中,我们经常会遇到一些原理性的问题,很常识但很难用通俗的语言解释清楚,这也是大部分业务级程序员经常失误的地方.虽然写了多年代码,但是核心思想不清,导致自己的后续发展受限,这是一个优秀的程序员和普 ...