写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.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. 2D空间中求线段与圆的交点

    出处: https://answers.unity.com/questions/366802/get-intersection-of-a-line-and-a-circle.html 测试脚本(返回值 ...

  2. 【iCore4 双核心板_FPGA】例程十一:FSMC总线通信实验——独立地址模式

    实验原理: STM32F767上自带FMC控制器,本实验将通过FMC总线的地址独立模式实现STM32与FPGA 之间通信,FPGA内部建立RAM块,FPGA桥接STM32和RAM块,本实验通过FSMC ...

  3. java.util.concurrent介绍【转】

    java.util.concurrent介绍   java.util.concurrent 包含许多线程安全.测试良好.高性能的并发构建块.不客气地说,创建 java.util.concurrent ...

  4. app嵌入的H5页面的数据埋点总结

    好久没写博客了,大半年时间花费在了许多杂事上. 最近1个月专门为H5页面的app开发了一些埋点功能,主要是考虑到以后的可复制性和通用型,由于不是前端开发出身,相对来说还是比较简陋的. 正题开始:H5页 ...

  5. Sphinx 2.2.11-release reference manual

    1. Introduction 1.1. About 1.2. Sphinx features 1.3. Where to get Sphinx 1.4. License 1.5. Credits 1 ...

  6. Java如何使服务器允许连接到套接字端口?

    在Java编程中,如何使服务器允许连接到套接字端口? 以下示例显示如何使服务器通过使用ServerSocket类的server.accept()方法和Socket类的sock.getInetAddre ...

  7. portfolio

    1.工作量计算逻辑: 原始待办事项: 预估2个冲刺,如下图所示: Sprint1的故事点计划工作量5,空闲工作量28.如下图 Sprint2为预估冲刺,指的是预估待办事项在后续冲刺的预估计划,后续冲刺 ...

  8. websphere 删除文件

    META-INF 文件夹下加入ibm-partialapp-delete.props即可 里面添加路径 如WEB-INF/xxx/xxx.xxx

  9. react 生命周期钩子里不要写逻辑,否则不生效

    react 生命周期钩子里不要写逻辑,否则不生效,要把逻辑写在函数里,然后在钩子里调用函数,否则会出现问题.

  10. js给原型增加新属性和方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...