基于TCP的客户端、服务器端socket编程

一.实验目的

理解tcp传输客户端服务器端通信流程

二.实验平台

MAC OS

三.实验内容

编写TCP服务器套接字程序,程序运行时服务器等待客户的连接,一旦连接成功,则显示客户的IP地址、端口号,并向客户端发送字符串。

四.实验原理

使用TCP套接字编程可以实现基于TCP/IP协议的面向连接的通信,它分为服务器端和客户端两部分,其主要实现过程如下

服务器端代码:

  1 #include "iostream"
  2 #include "netdb.h"
  3 #include "stdio.h"
  4 #include "stdlib.h"
  5 #include "sys/socket.h"
  6 #include "unistd.h"
  7 #include "arpa/inet.h"
  8 #include "string.h"
  9 #include "memory.h"
 10 #include "signal.h"
 11 #include "time.h"
 12
 13 int sockfd;
 14
 15 void sig_handler(int signo)
 16 {
 17     if(signo==SIGINT)
 18     {
 19         printf("Server close \n");
 20         close(sockfd);
 21         exit(1);
 22     }
 23 }
 24
 25 //输出连接上来的客户端相关信息
 26 void out_addr(struct sockaddr_in *clientaddr)
 27 {
 28     //将端口从网络字节序转成主机字节序
 29     int port =ntohs(clientaddr->sin_port);
 30     char ip[16];
 31     memset (ip,0,sizeof(ip));
 32     inet_ntop(AF_INET,
 33             &clientaddr->sin_addr.s_addr,ip,sizeof(ip));
 34     printf("client:%s(%d)connected\n",ip,port);
 35 }
 36
 37 void do_service(int fd)
 38 {
 39     //获取系统时间
 40     long t=time(0);
 41     char *s=ctime(&t);
 42     size_t size=strlen(s)*sizeof(char);
 43     //将服务器端的系统时间写到客户端
 44     if(write(fd,s,size)!=size)
 45     {
 46         perror("write error");
 47     }
 48 }
 49
 50 int main(int argc,char *argv[])
 51 {
 52     if(argc<2)
 53     {
 54         printf("usage:%s #port\n",argv[0]);
 55         exit(1);
 56     }
 57
 58     if(signal(SIGINT,sig_handler)==SIG_ERR)
 59     {
 60         perror("signal sigint error");
 61         exit(1);
 62     }
 63
 64     /*1. 创建socket
 65      AF_INT:ipv4
 66      SOCK_STREAM:tcp协议
 67     */
 68     sockfd=socket(AF_INET,SOCK_STREAM,0);
 69     if(sockfd<0){
 70         perror("socket error");
 71         exit(1);
 72     }
 73
 74     /*2:调用bind函数绑定socket和地址*/
 75
 76     struct sockaddr_in serveraddr;
 77     memset(&serveraddr,0,sizeof(serveraddr));
 78     //往地址中填入ip,port,internet类型
 79     serveraddr.sin_family=AF_INET;  //ipv4
 80     serveraddr.sin_port=htons(atoi(argv[1]));  //htons主机字节序转成网络字节序
 81
 82     serveraddr.sin_addr.s_addr=INADDR_ANY;
 83
 84     if(bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))<0)
 85     {
 86         perror("bind error");
 87         exit(1);
 88
 89     }
 90
 91     /*调用listen函数监听(指定port监听)
 92     通知操作系统区接受来自客户顿的连接请求
 93     第二个参数:指定队列长度
 94     */
 95
 96     if(listen(sockfd,10)<0)
 97     {
 98         perror("listen error");
 99
100     }
101
102     /*调用accept函数从队列中获得一个客户端的请求连接
103     */
104
105     struct sockaddr_in clientaddr;
106     socklen_t clientaddr_len=sizeof(clientaddr);
107
108     while(1){
109         int fd=accept(sockfd,
110                 (struct sockaddr*)&clientaddr,
111                   &clientaddr_len);
112         if(fd<0){
113             perror("accept error");
114             continue;
115         }
116
117         /*5.调用IO函数(read/write)和
118             连接的客户端进行双向通信
119         */
120         out_addr(&clientaddr);
121         do_service(fd);
122
123         /*6.关闭socket*/
124         close(fd);
125     }
126
127     return 0;
128 }

客户端代码:

 1 #include "netdb.h"
 2 #include "sys/socket.h"
 3 #include "stdio.h"
 4 #include "stdlib.h"
 5 #include "string.h"
 6 #include "memory.h"
 7 #include "unistd.h"
 8 #include <arpa/inet.h>
 9
10 int main(int argc,char *argv[])
11 {
12     if(argc<3)
13     {
14         printf("usage:%s ip port \n",argv[0]);
15         exit(1);
16     }
17
18     /*步骤1:创建socket*/
19     int sockfd=socket(AF_INET,SOCK_STREAM,0);
20     if(sockfd<0)
21     {
22         perror("socket error");
23         exit(1);
24     }
25
26     struct sockaddr_in serveraddr;
27     memset(&serveraddr,0,sizeof(serveraddr));
28     serveraddr.sin_family=AF_INET;
29     serveraddr.sin_port=htons(atoi(argv[2]));
30
31     //主机字节序转换成网络字节序
32     inet_pton(AF_INET,argv[1],
33             &serveraddr.sin_addr.s_addr);
34
35     /*步骤2:客户端调用connect函数连接到服务器
36
37     */
38     if(connect(sockfd,(struct sockaddr*)&serveraddr,
39                 sizeof(serveraddr))<0)
40     {
41         perror("connect error");
42         exit(1);
43     }
44
45     /*步骤3:调用IO函数(read/write)和服务器端双向通信*/
46     char buffer[1024];
47     memset(buffer,0,sizeof(buffer));
48     size_t size;
49
50     if((size=read(sockfd,
51                     buffer,sizeof(buffer)))<0)
52     {
53         perror("read error");
54     }
55
56     if(write(STDOUT_FILENO,buffer,size)!=size)
57     {
58         perror("write error");
59     }
60 }

实验结果:

时间: 2024-07-30 13:41:33

基于TCP的客户端、服务器端socket编程的相关文章

基于TCP协议下的socket编程

socket: TCP/IP协议中一个端口号和一个IP地址绑定在一起就生成一个socket就表示了网络中唯一的一个进程,它是全双工的工作方式. 基于TCP的socket编程 函数的使用: 1.socket()         #include <sys/types.h>          /* See NOTES */        #include <sys/socket.h>        int socket(int domain, int type, int protoco

基于 TCP/IP 协议的网络编程

在说明基于 TCP/IP 协议的网络编程之前,先来了解一下 Socket(网络套接字): 利用套接字(Socket)开发网络应用程序早已被广泛的采用,以至于成为事实上的标准 通信的两端都要有 Socket,是两台机器间通信的端点(API 原话) 网络通信其实就是 Socket 间的通信 Socket 允许程序把网络连接当成一个流,数据在两个 Socket 间通过 IO 传输 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端 网络编程某种程度上可以称作"Socket 编程" T

基于UDP协议的socket套接字编程 基于socketserver实现并发的socket编程

基于UDP协议 的socket套接字编程 1.UDP套接字简单示例 1.1服务端 import socket server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 建立一个UDP协议的服务器 server.bind(("127.0.0.1",8080)) while True: data,addr = server.recvfrom(1024) server.sendto(data.upper(),addr) server

基于TCP协议的简单Socket通信笔记(JAVA)

好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些网络编程的基础,这里就不提了,只记录最简单易懂实用的东西. 1.首先先来看下基于TCP协议Socket服务端和客户端的通信模型: Socket通信步骤:(简单分为4步) 1.建立服务端ServerSocket和客户端Socket 2.打开连接到Socket的输出输入流 3.按照协议进行读写操作 4.关闭相对应的资源 2.相关联的API: 1.首先先来看下S

C++基于TCP和UDP的socket通信

以下是关于socket编程的一个非常经典的例子: 服务端: #include <stdio.h> #include <Winsock2.h> //windows socket的头文件 #pragma comment( lib, "ws2_32.lib" )// 链接Winsock2.h的静态库文件 void main() { //初始化winsocket WORD wVersionRequested; WSADATA wsaData; int err; wVer

103 基于socketserver实现并发的socket编程

目录 一.socketserver模块 1.1 源码分析总结: 二.基于TCP协议 二.基于UDP协议 一.socketserver模块 基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环 socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题) Server类: request类: 继承关系: 以下述代码为例,分析socketserver源码: ftpserver=socketserver.ThreadingTCPServer(('

基于socketserver实现并发的socket编程

一.基于TCP协议 基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环 socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题) 1.1server类 [ 1.2 request类 [ 1.3 继承关系 [ [ [ 1.4 服务端 # 使用socketserver写服务端 # 导入模块 import socketserver # 自己定义一个类, 必须继承BaseRequestHandler class Mytcp(socketser

java 网络编程 TCP协议 java 服务器和客户端 java socket编程

一个 HelloWord 级别的 Java Socket 通信的例子.通讯过程:        先启动 Server 端,进入一个死循环以便一直监听某端口是否有连接请求.然后运行 Client 端,客户端发出连接请求,服务端监听到这次请求后向客户端发回接受消息,连接建立,启动一个线程去处理这次请求,然后继续死循环监听其他请求.客户端输入字符串后按回车键,向服务器发送数据.服务器读取数据后回复客户端数据.这次请求处理完毕,启动的线程消亡.如果客户端接收到 "OK" 之外的返回数据,会再次

TCP与UDP在socket编程中的区别 (网络收集转载)

http://blog.chinaunix.net/uid-26421509-id-3814684.html 一.TCP与UDP的区别 基于连接与无连接  对系统资源的要求(TCP较多,UDP少)  UDP程序结构较简单  流模式与数据报模式  TCP保证数据正确性,UDP可能丢包  TCP保证数据顺序,UDP不保证  部分满足以下几点要求时,应该采用UDP 面向数据报方式 网络数据大多为短消息  拥有大量Client  对数据安全性无特殊要求  网络负担非常重,但对响应速度要求高  具体编程时