当前位置: 首页 > 编程日记 > 正文

[linux][c语言]用socket实现简单的服务器客户端交互

Socket解释:

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。
socket交互原理图解

连接过程:

根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
socket连接过程图解

mac环境编译

client.c

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>  /* netdb is necessary for struct hostent */#define PORT 4321   /* server port */#define MAXDATASIZE 100int main(int argc, char *argv[])
{int sockfd, num;    /* files descriptors */char buf[MAXDATASIZE];    /* buf will store received text */struct hostent *he;    /* structure that will get information about remote host */struct sockaddr_in server;if (argc != 2){printf("Usage: %s <IP Address>\n",argv[0]);exit(1);}if((he=gethostbyname(argv[1]))==NULL){printf("gethostbyname() error\n");exit(1);}if((sockfd=socket(AF_INET,SOCK_STREAM, 0))==-1){printf("socket() error\n");exit(1);}bzero(&server,sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(PORT);server.sin_addr = *((struct in_addr *)he->h_addr);if(connect(sockfd, (struct sockaddr *)&server, sizeof(server))==-1){printf("connect() error\n");exit(1);}char str[] = "你好啊服务器!\n";if((num=send(sockfd,str,sizeof(str),0))==-1){printf("send() error\n");exit(1);}if((num=recv(sockfd,buf,MAXDATASIZE,0))==-1){printf("recv() error\n");exit(1);}buf[num-1]='\0';printf("server message: %s\n",buf);close(sockfd);return 0;
}

server.c

#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define PORT 4321#define BACKLOG 1
#define MAXRECVLEN 1024int main(int argc, char *argv[])
{char buf[MAXRECVLEN];int listenfd, connectfd;   /* socket descriptors */struct sockaddr_in server; /* server's address information */struct sockaddr_in client; /* client's address information */socklen_t addrlen;/* Create TCP socket */if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){/* handle exception */perror("socket() error. Failed to initiate a socket");exit(1);}/* set socket option */int opt = SO_REUSEADDR;setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));bzero(&server, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(PORT);server.sin_addr.s_addr = htonl(INADDR_ANY);if(bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1){/* handle exception */perror("Bind() error.");exit(1);}if(listen(listenfd, BACKLOG) == -1){perror("listen() error. \n");exit(1);}addrlen = sizeof(client);while(1){if((connectfd=accept(listenfd,(struct sockaddr *)&client, &addrlen))==-1){perror("accept() error. \n");exit(1);}struct timeval tv;gettimeofday(&tv, NULL);printf("You got a connection from client's ip %s, port %d at time %ld.%ld\n",inet_ntoa(client.sin_addr),htons(client.sin_port), tv.tv_sec,tv.tv_usec);int iret=-1;while(1){iret = recv(connectfd, buf, MAXRECVLEN, 0);if(iret>0){printf("%s\n", buf);}else{close(connectfd);break;}/* print client's ip and port */send(connectfd, buf, iret, 0); /* send to the client welcome message */}}close(listenfd); /* close listenfd */return 0;
}

命令行执行 $ gcc client.c -o client,可以编译出客户端程序。
命令行执行$ gcc server.c -o server,可以编译出服务端程序。

命令行执行$ ./server,启动server程序。

重新打开一个命令行窗口
执行 $ ./client 127.0.0.1,启动客户端程序

本程序客户端会自动退出,服务器不会,因此如果想停掉服务器程序,直接在命令行界面按键盘Ctrl+C停止。

程序实现的功能很简单,就是服务器监听4321端口,客户端与之建立TCP连接后,再发送字符串“你好啊服务器!\n”到服务端,服务端打印出来,然后再把字符串传回给客户端,客户端再打印出来。然后客户端关闭连接退出,而服务端继续监听4321端口等待下一次连接。

转载于:https://www.cnblogs.com/-oreo/p/10013216.html

相关文章:

Spring之注解方式实例化Java类

我们知道一个<bean></bean>就代表一个对象&#xff0c;如果想创建多个对象&#xff0c;就要使用多个<bean></bean>&#xff0c;所以这里有个简便的方法&#xff1a; <context:component-scan base-package"com.jd"></context:comp…

3.Linux Shell流程控制

1.if/else结构 if condition thenstatements elif condition thenstatements elsestatements fi 2.条件 与C语言不同的是&#xff0c;条件(condition)实际上是语句列表&#xff0c;而不是一般的布尔表达式。 按照惯例&#xff0c;函数以及命令的退出状态用0表示成功&#xff0c…

ASP.NET 2.0 中配合 Master Page 使用的优化 CSS 模型

ASP.NET 2.0 中增加了内建的 MasterPage 的支持&#xff0c;这对我们来说是一个很大的便利。然而经过一段时间的使用&#xff0c;我发现 MasterPage 并不是那么完美&#xff1a;嵌套的 MasterPage 不能支持设计时界面&#xff0c;以及下面要提到的Content Page 中增加 CSS 的问…

详细说明Spring--AOP

这篇博客较长&#xff0c;耐心读完或许会有“柳暗花明又一村”的感觉哦&#xff01; 为什么? 我先不说AOP是什么&#xff0c;我先说说为什么要用AOP&#xff0c;依照惯例&#xff0c;我还是先举一个例子&#xff1a; 先把项目结构展现出来&#xff1a; 我们先在com.jd.calcu…

ES6中的Promise详解

Promise 在 JavaScript 中很早就有各种的开源实现&#xff0c;ES6 将其纳入了官方标准&#xff0c;提供了原生 api 支持&#xff0c;使用更加便捷。 定义 Promise 是一个对象&#xff0c;它用来标识 JavaScript 中异步操作的状态&#xff08;pending, resolve, reject&#xff…

Jquery 将表单序列化为Json对象

大家知道Jquery中有serialize方法&#xff0c;可以将表单序列化为一个“&”连接的字符串&#xff0c;但却没有提供序列化为Json的方法。不过&#xff0c;我们可以写一个插件实现。 我在网上看到有人用替换的方法&#xff0c;先用serialize序列化后&#xff0c;将&替换成…

ASP.NET常用函数

Abs(number) 取得数值的绝对值。 Asc(String) 取得字符串表达式的第一个字符ASCII 码。 Atn(number) 取得一个角度的反正切值。 CallByName (object, procname, usecalltype,[args()]) 执行一个对象的方法、设定或传回对象的属性。 CBool(expression) 转换表达式为Boolean …

简单快速修改大量重复代码(Intellij IDEA)

血与泪的教训啊&#xff01;&#xff01;&#xff01;刚开始不知道&#xff0c;一味地疯狂点鼠标和键盘&#xff0c;点到手抽筋才想起来百度一下如何快速修改大量重复代码&#xff0c;呜呜呜~~~ 给大家分享一下吧&#xff0c;可以节约大家大量的时间哦&#xff1a; …

5.3Role和Claims授权「深入浅出ASP.NET Core系列」

5.3Role和Claims授权「深入浅出ASP.NET Core系列」 原文:5.3Role和Claims授权「深入浅出ASP.NET Core系列」希望给你3-5分钟的碎片化学习&#xff0c;可能是坐地铁、等公交&#xff0c;积少成多&#xff0c;水滴石穿&#xff0c;码字辛苦&#xff0c;如果你吃了蛋觉得味道不错&…

電子商務新紀元-WebService With BizSnap

電子商務新紀元-WebService With BizSnap WebService SOAP(Simple Object Access Protocol) Web Services Description Language (WSDL) DELPHI 的SOAP 撰寫WebService Server 程式 撰寫Client 端程式 魔法的秘密 傳送複雜型態資料(Complex Type) 傳送檔案或圖形 處理資料庫 C…

mysql优化1

1.以空间换时间,减少连表查询的次数,适当增加冗余字段 例如: 计算的字段,可以事先统计完,方数据库中,来一个加一个,而不用现场计算 2.字段类型: 整型 > date,time >enum >char >varchar >blob,text 字符串需要考虑字符集和校对集,因此比整型慢 time会考虑时期,用…

用XP做服务器突破10人限制

用XP做服务器突破10人限制用微软提供的小工具 MetaEdit&#xff0c;最新版本是2.2。下载地址:http://download.microsoft.com/download/iis50/Utility/5.0/NT45/EN-US/MtaEdt22.exe安装好以后将树型目录展开至LM \ W3SVC直接在W3SVC文件夹上单击&#xff0c;选择右边列表中Name…

Java反射(详述版)

一、什么是反射&#xff1f; 我们先来看一个例子&#xff1a; package venus; public class Student {public String name;public Student(){System.out.println("无参构造方法");}public void doHomework(){System.out.println(name "正在做作业~~~");…

s9.16作业,员工信息表

转载https://blog.csdn.net/qq_35883464/article/details/83151464 实现员工信息表文件存储格式如下&#xff1a;id&#xff0c;name&#xff0c;age&#xff0c;phone&#xff0c;job1,Alex,22,13651054608,IT2,Egon,23,13304320533,Tearcher3,nezha,25,1333235322,IT 现在需要…

Dubbo+zookeeper使用方法以及注意事项

Dubbozookeeper使用方法以及注意事项最近在一个项目中想做一个数据库查询的服务&#xff0c;目的是将数据库查询这块从程序中脱离出来&#xff0c;形成一个公共的服务平台&#xff0c;大家都可以调用&#xff0c;经过考虑决定选用Dubbozookeeper这个经典的组合来实现&#xff0…

淘淘经受了一次考验...

18日去香港给一个潜在客户做了一次演示&#xff0c;顺便帮淘淘买了一罐奶粉&#xff0c;因为听说香港的奶粉质量比较好&#xff0c;是原装进口的。下午6点多回到深圳&#xff0c;没想到&#xff0c;听到一个不太好的消息。淘淘的奶奶推车带淘淘出去的时候&#xff0c;不小心&am…

使用MasterPage遇到的问题

最近重新拿起.NET&#xff0c;发现一切变的那么的陌生了&#xff0c;发展得真是快啊。。。在使用MasterPage时&#xff0c;要从一个页面的Form提交数据到另一个页面的Form&#xff0c;应该如何处理&#xff1f;不使用MasterPage的时候&#xff0c;可以直接使用PostBackUrl"…

Machine Learning——DAY1

监督学习&#xff1a;分类和回归 非监督学习&#xff1a;聚类和非聚类 1.分类和聚类的区别&#xff1a; 分类(Categorization or Classification)就是按照某种标准给对象贴标签(label)&#xff0c;再根据标签来区分归类。 聚类是指事先没有“标签”而通过某种成团分析找出事物之…

Java的注解

一、注解的概念&#xff1a; 注解并不是一开始就有的&#xff0c;JDK5之前是没有注解的&#xff0c;JDK5及其以后JDK版本才开始支持Java注解&#xff01; Java注解&#xff08;Annotation&#xff09;也叫做元数据&#xff0c;以注解名在代码中存在&#xff0c;它是一种在源代码…

activemq的学习,第一篇

本地的activemq的地址&#xff1a; http://localhost:8161/admin/ win10的启动avtivemq E:\Program Files\ActiveMQ\apache-activemq-5.15.3\bin\win64 win64里面的activemq.bat 消息队列的学习 学习地址2 这是spring集合activemq的地址&#xff1a;github pom.xml引入的依赖&a…

CS Tip 16: 利用注释

译自: http://soup.co.za/weblog/archive/2006/04/07/CS-Tip-16_3A00_-Commenting-out-controls.aspx 当您在修改皮肤时您可以修改任何HTML标记&#xff0c;但是除了带有runat"Server"的除外&#xff0c;删除掉将会产生错误 如果您不想某个控件显示在页面上您可以注释…

今天没有浪费时间,我努力了

7月12日经过暴雨洗礼过的清晨&#xff0c;我晚起了一会&#xff0c;我伧促的洗了把脸&#xff0c;瞪起朦胧胧的双眼&#xff0c;迈着疲惫步子&#xff0c;重复着这条凌乱的街道&#xff0c;10分钟多一点&#xff0c;我就到了公交站点&#xff0c;像往常一样&#xff0c;挤上了8…

动态规划——洛谷_P1057传球游戏

题目&#xff1a; 题目描述 上体育课的时候&#xff0c;小蛮的老师经常带着同学们一起做游戏。这次&#xff0c;老师带着同学们一起做传球游戏。游戏规则是这样的&#xff1a;n个同学站成一个圆圈&#xff0c;其中的一个同学手里拿着一个球&#xff0c;当老师吹哨子时开始传球&…

多线程1(进程、[创建]线程与生命周期)

一、进程与线程 什么是进程&#xff1f;我们先说说什么是程序&#xff1f; 程序&#xff08;Program&#xff09;是为实现特定目标或解决特定问题而用计算机语言&#xff08;比如Java、C等&#xff09;编写的命令序列的集合。 进程&#xff08;process&#xff09;就是指一个程…

网络操作系统第四章

1. 磁盘的数据结构包括哪些内容&#xff1f; 答&#xff1a;分区&#xff0c;卷&#xff0c;磁盘分区&#xff0c;主分区&#xff0c;扩展分区&#xff0c;逻辑分区&#xff0c;逻辑驱动器&#xff0c;引导分区。 2. 什么是基本磁盘和动态磁盘&#xff1f; &#xff08;…

广播风暴系列专题(一)广播风暴:发现-端口

近日防火墙经常地检测到"svchost UDP/连入192.168.1.255/137 192.168.1.66/137 1055656/1065732 UDP_WAIT 过滤 8:48:31 C:\WINDOWS\system32\svchost.exe";"services UDP/连出 192.168.1.21/137 192.168.1.255/137 920736/913476 UDP_WAIT 过滤 11:46:3…

显示一个顶层的提示信息

vb里常作&#xff0c;大概的思路就是显示一个顶层的窗体&#xff0c;提示暂时不要动。c&#xff03;里更简单了MsgDlg msgnewMsgDlg(); msg.TopMosttrue; msg.Show(); System.Windows.Forms.Application.DoEvents();

ArcGIS Engine开发-TOCControl中实现图层的拖放

TOCControl非常好&#xff0c;不用写一行代码就可以将整个地图的图层信息况显示出来&#xff1b;TOCControl也非常坏&#xff0c;提供的接口非常少&#xff0c;我认为有用的只有三个&#xff1a;HitTest,SetBuddyControl,Update&#xff0c;而且Update方法一执行&#xff0c;整…

多线程2(常用的方法:join、interrupt、currentThread、isAlive、setDaemon...)

常用的方法&#xff1a; 1、join()方法&#xff1a;join()方法&#xff1a;执行该方法的线程进入阻塞状态&#xff0c;直到调用该方法的线程结束后再由阻塞状态转为就绪状态。 示例&#xff1a; package venus;import java.util.Date;public class Test {public static void m…

Oracle总结第二篇【视图、索引、事务、用户权限、批量操作】

前言 在Oracle总结的第一篇中&#xff0c;我们已经总结了一些常用的SQL相关的知识点了…那么本篇主要总结关于Oralce视图、序列、事务的一些内容… 在数据库中&#xff0c;我们可以把各种的SQL语句分为四大类… &#xff08;1&#xff09;DML&#xff08;数据操纵语言&#xff…