写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文!

本博客全网唯一合法URL:http://www.cnblogs.com/acm-icpcer/p/9073801.html

(本篇博客参考了:https://www.cnblogs.com/xiaojiang1025/archive/2016/10/11/5950458.html,源码为我自己所写)

基本模型:

 

核心代码:

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//服务器: socket() //创建socket
struct sockaddr_in //准备通信地址
bind() //绑定socket和addr
listen() //创建listening socket
accept() //创建connect socket
send()/recv() //进行通信
close() //关闭socket //客户端: socket() //创建socket
准备通信地址:服务器的地址
connect() //链接socket和通信地址
send()/recv() //进行通信
close() //关闭socket

关键函数解释:

bind()

//把通信地址和socket文件描述符绑定,用在服务器端,成功返回0,失败返回-1设errno

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd: socket文件的fd(returned by socket())

addr: 需要强制类型转换成socketaddr_un或soketaddr_in, 参见上

addrlen: 通信地址的大小, 使用sizeof();

listen()

//创建侦听socket,把sockfd标记的socket标记为被动socket,被动socket表示这个socket只能用来接收即将到来的连接请求,不再用于读写操作和通信,接收连接请求的是accept()

//成功返回0,失败返回-1设errno

int listen(int sockfd, int backlog);

backlog:排队等待“被响应”连接请求队列的最大长度 eg: 接待室的最大长度

accept()

//创建连接socket,返回连接socket的文件描述符,成功返回文件描述符,失败返回-1设errno

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

addr : 结构体指针, 用于带出客户端的通信地址

addlen : 结构体指针, 用于带出通信地址的大小

ATTENTION: listen()把socket()创建的sockfd变为listening socket, 负责侦听哪个client连接上了(即不但要知道连上没, 还要知道谁连上了, 这个SOCK_STREAM的socket有这个能力), accept()提取排队中的最上面的一个client, 给它一个conneted socket, 这样这个client就可以和server沟通了, 就是说这里有两个socket, 一个负责侦听一个负责通信

send()

//向指定的socket发送指定的数据,成功返回实际发送数据的大小,失败返回-1设errno

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

sockfd: 用于通信的socket描述符(returned by accept())

buf : 被发送数据的缓冲区首地址

len : 被发送数据的大小

flags: 发送的标志, 如果给0等同于write()

recv()

//从指定的socket接收数据,成功返回接收的数据的大小,失败返回-1设errno

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

sockfd: 用于通信的socket描述符(returned by accept())

buf: 接收数据的缓冲区首地址

len: 接收数据的大小

flags: 发送的标志, 如果给0等同于read()

connect()

//初始化一个socket的连接,用在客户端,成功返回0,失败返回-1设errno

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd: socket文件的fd(returned by socket())

addr: 需要强制类型转换成socketaddr_un或soketaddr_in, 参见上

addrlen: 通信地址的大小, 使用sizeof();

源代码:

1、client端:

/*
./server (local ip) 7575
自己ip 端口
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> #define MAXBUF 1024 int main(int argc, char **argv)
{
int sockfd, len;
struct sockaddr_in dest;
char buffer[MAXBUF + ];
if (argc != )
{
printf(" error format,it must be:\n\t\t%s IP port\n",argv[]);
exit(EXIT_FAILURE);
} if ((sockfd = socket(AF_INET, SOCK_STREAM, )) < ) {
perror("Socket");
exit(errno);
}
printf("socket created\n"); bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(atoi(argv[]));
if (inet_aton(argv[], (struct in_addr *) &dest.sin_addr.s_addr) == )
{
perror(argv[]);
exit(errno);
}
if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest))==-)
{
perror("Connect ");
exit(errno);
}
printf("server connected\n"); while () {
bzero(buffer, MAXBUF + );
len = recv(sockfd, buffer, MAXBUF, );
if (len > )
printf("recv successful:'%s',%d byte recv\n",buffer, len);
else {
if (len < )
printf("send failure,errno code is %d,err message is '%s'\n",errno, strerror(errno));
else
printf("the other one close ,quit\n");
break;
}
bzero(buffer, MAXBUF + );
printf("pls send message to send:");
fgets(buffer, MAXBUF, stdin);
if (!strncasecmp(buffer, "quit", ))
{
printf(" i will quit!\n");
break;
}
len = send(sockfd, buffer, strlen(buffer) - , );
if (len < )
{
printf("message '%s' send failure,errno code is %d,errno message is '%s'\n",buffer, errno, strerror(errno));
break;
} else
printf("message:%s\tsend successful,%dbyte send!\n",buffer, len);
}
close(sockfd);
return ;
}

2、server端:

/*
./server (local ip) 7575 5
自己ip 端口 等待队列大小
ifconfig -a
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h> #define MAXBUF 1024 int main(int argc, char *argv[])
{
int pid; int sockfd, new_fd;
socklen_t len;
struct sockaddr_in my_addr, their_addr;
unsigned int myport, lisnum;
char buf[MAXBUF + ]; if (argv[])
myport = atoi(argv[]);
else
myport = ; if (argv[])
lisnum = atoi(argv[]);
else
lisnum = ; if ((sockfd = socket(AF_INET, SOCK_STREAM, )) == -)
{
perror("socket");
exit(EXIT_FAILURE);
} bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(myport);
if (argv[])
my_addr.sin_addr.s_addr = inet_addr(argv[]);
else
my_addr.sin_addr.s_addr = INADDR_ANY; if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))== -)
{
perror("bind");
exit(EXIT_FAILURE);
} if (listen(sockfd,lisnum ) == -)
{
perror("listen");
exit(EXIT_FAILURE);
}
printf("wait for connect\n");
len = sizeof(struct sockaddr);
if ((new_fd =accept(sockfd, (struct sockaddr *) &their_addr,&len)) == -)
{
perror("accept");
exit(EXIT_FAILURE);
}
else
printf("server: got connection from %s, port %d, socket %d\n",inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port), new_fd); while ()
{
printf("newfd=%d\n",new_fd);
bzero(buf, MAXBUF + );
printf("input the message to send:");
fgets(buf, MAXBUF, stdin);
if (!strncasecmp(buf, "quit", ))
{
printf("i will close the connect!\n");
break;
}
len = send(new_fd, buf, strlen(buf) - , );
if (len > )
printf("message:%s\t send sucessful,send %dbyte!\n",buf, len);
else
{
printf("message'%s' send failure!errno code is %d,errno message is '%s'\n",buf, errno, strerror(errno));
break;
}
bzero(buf, MAXBUF + ); len = recv(new_fd, buf, MAXBUF, );
if (len > )
printf("message recv successful :'%s',%dByte recv\n",buf, len);
else
{
if (len < )
printf("recv failure!errno code is %d,errno message is '%s'\n",errno, strerror(errno));
else
printf("the other one close quit\n");
break;
}
}
close(new_fd);
close(sockfd);
return ;
}

运行示例:

PS(被蔡总玩坏了的tcp,23333):

tz@COI HZAU

2018/5/22

Linux下TCP/socket编程的更多相关文章

  1. Linux下TCP网络编程与基于Windows下C#socket编程间通信

    一.linux下TCP网络编程基础,需要了解相关函数 Socket():用于套接字初始化. Bind():将 socket 与本机上的一个端口绑定,就可以在该端口监听服务请求. Listen():使s ...

  2. Linux下Golang Socket编程原理分析与代码实现

    在POSIX标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带Runtime的跨平台编程语言,Go中提供给开发者的Socket API是建立在操作系统原生Socket ...

  3. Linux下网络socket编程——实现服务器(select)与多个客户端通信

    一.关于socket通信 服务器端工作流程: 调用 socket() 函数创建套接字 用 bind() 函数将创建的套接字与服务端IP地址绑定 调用listen()函数监听socket() 函数创建的 ...

  4. LINUX 下 ipv6 socket 编程

    大家都知道,随着互联网上主机数量的增多,现有的32位IP地址已经不够用了,所以推出了下一代IP地址IPv6,写网络程序的要稍微改变一下现有的网络程序适应IPv6网络是相当容易的事.对于我们来说就是IP ...

  5. 网络编程学习笔记:linux下的socket编程

    socket是进程通信的一种方式,通过调用一些API可以实现进程间通信,建立连接以及收发信息的过程如下图所示: 这些函数的用法如下: 1.int socket(int protocolFamily, ...

  6. c++ 网络编程(一)TCP/UDP windows/linux 下入门级socket通信 客户端与服务端交互代码

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9601511.html c++ 网络编程(一)TCP/UDP  入门级客户端与服务端交互代码 网 ...

  7. ZT Linux系统环境下的Socket编程详细解析

    Linux系统环境下的Socket编程详细解析 来自: http://blog.163.com/jiangh_1982/blog/static/121950520082881457775/ 什么是So ...

  8. Linux下的C编程实战

    Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来, Linu ...

  9. winsock教程- windows下的socket编程(c语言实现)

    winsock教程- windows下的socket编程(c语言实现) 使用winsock进行socket 编程     这是一个学习windows下socket编程(c语言)的快速指南.这是因为一下 ...

随机推荐

  1. Spring Boot 2.0 整合 FreeMarker 模板引擎

    本篇博文将和大家一起使用Spring Boot 2.0 和FreeMarker 模板引擎整合实战. 1. 创建新的项目 2. 填写项目配置信息 3. 勾选web 模块 4. 勾选freemarker模 ...

  2. 严苛模式 strictmode

    参考链接 http://blog.csdn.net/brokge/article/details/8543145 一.严苛模式-虚拟机策略 虚拟机策略(VmPolicy)能检查内存泄漏,譬如,当关闭一 ...

  3. 【Java多线程】JDK1.5并发包API杂谈

    并发与并行 并发 一个或多个处理器执行更多的任务(通过划分时间片来执行更多的任务),从逻辑上实现同时运行: 如,N个并发请求在一个两核CPU上: 并行 N个处理器分别同时执行N个任务,从物理上实现同时 ...

  4. asp.net Request、Request.Form、Request.QueryString的区别(转)

    Request.Form:获取以POST方式提交的数据. Request.QueryString:获取地址栏参数(以GET方式提交的数据). Request:包含以上两种方式(优先获取GET方式提交的 ...

  5. java框架篇---hibernate(一对多)映射关系

    一对多关系可以分为单向和双向. 一对多关系单向 单向就是只能从一方找到另一方,通常是从主控类找到拥有外键的类(表).比如一个母亲可以有多个孩子,并且孩子有母亲的主键作为外键.母亲与孩子的关系就是一对多 ...

  6. 【iCore1S 双核心板_FPGA】例程一:GPIO输出实验——点亮LED

    实验现象: 三色LED循环点亮. 核心源代码: //--------------------Module_LED-----------------------------// module LED( ...

  7. SwingWorker

    Swing应用程序员常见的错误是误用Swing事件调度线程(Event DispatchThread,EDT).他们要么从非UI线程访问UI组件:要么不考虑事件执行顺序:要么不使用独立任务线程而在ED ...

  8. CentOS7 配置免密码登陆

    3台主机 192.168.30.207 Master 192.168.30.251 Node1 192.168.30.252 Node2 三台主机检查 ~/.ssh 文件夹,没有则新建 在master ...

  9. Java如何从IP地址查找主机名?

    在Java编程中,如何从IP地址查询出主机名? 以下示例显示了如何通过net.InetAddress类的InetAddress.getByName()方法将指定的IP地址查到主机名称. package ...

  10. file_name[:-4]

    file_name: chair_0001.off file_name[:-4] : chair_0001