写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.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. ASP.NET CORE中判断是否移动端打开网页

    using Microsoft.AspNetCore.Http;using System;using System.Collections.Generic;using System.Text;usin ...

  2. Unity的Attribute(特性)还算多吧

    属性 (Attribute) 使用 Unity 的C#语言 ,利用属性(Attribute)来类定义和变量定义或区分其他的变量,您可以设置一种特殊行为.* 1 例如,您添加[SerializeFiel ...

  3. JAVA(五)反射机制/Annotation

    成鹏致远 | lcw.cnblog.com |2014-02-04 反射机制 1.认识Class类 在正常情况下,必须知道一个类的完整路径之后才可以实例化对象,但是在 java中也允许通过一个对象来找 ...

  4. Adam算法

    结合了Momentum 和RMSprop算法的优点

  5. 5. BERT算法原理解析

    1. 语言模型 2. Attention Is All You Need(Transformer)算法原理解析 3. ELMo算法原理解析 4. OpenAI GPT算法原理解析 5. BERT算法原 ...

  6. spring 手动添加 bean 到容器,例子 :多数据源配置

    package com.thunisoft.spsjsb.config.db.decrypt; import com.alibaba.druid.pool.DruidDataSource; impor ...

  7. GitStack 第三方开源服务器端

      GitStack 开源集成Git的界面服务器端 官网URL:http://gitstack.com     详情 请看<分布式版本控制系统Git--使用GitStack+TortoiseGi ...

  8. Go指南练习_Reader

    https://tour.go-zh.org/methods/22 一.题目描述 实现一个 Reader 类型,它产生一个 ASCII 字符 'A' 的无限流. 二.题目分析 io 包指定了 io.R ...

  9. Java并发之volatile二

    使用volatilekeyword的场景 Volatile 变量具有 synchronized 的可见性特性.可是不具备原子特性.这就是说线程可以自己主动发现 volatile 变量的最新值.Vola ...

  10. Git合并最近的commit

    合并commit的做法一般用在pull request的时候,把开发同一功能时的所有琐碎的commit合并到一个(假装自己的代码是高质量代码(手动滑稽)).主要使用的命令是git rebase 或者g ...