回声TCP服务器端/客户端
一、TCP服务端
1、TCP服务端的默认函数调用顺序
- socket()创建套接字
- bind()分配套接字地址
- listen()等待请求连接状态
- accept()允许连接
- read()/write()数据交换
- close()断开连接
2、进入等待连接请求状态
只有调用了listen函数,客户端才能进入可发出连接请求的状态。即这时客户端才能调用connect()函数(若提前调用将发生错误)。
int listen(int sock, int backlog);
成功返回0,失败返回-1。sock指服务器端套接字,backlog指连接请求队列的长度,若为5,则队列长度为5,表示最多使5个连接请求进入队列。
3、受理客户端连接请求
int accept();
accept函数受理连接请求队列中待处理的客户端连接请求。函数调用成功时,accept函数内部将产生用于数据IO的套接字,并返回其文件描述符。需要强调的是,套接字是自动创建的,并自动与发起连接请求的客户端建立连接。
二、TCP客户端
1、TCP客户端的默认函数调用顺序
- socket()创建套接字
- connect()请求连接
- read/write数据交换
- close()断开连接
2、connect()
客户端调用connect函数后,发生以下情况之一才会返回(完成函数调用):
- 服务器端接收连接请求。
- 发生断网等异常情况而中断连接请求。
所谓的“接收连接”并不一位置服务器端调用accept函数,其实是服务器端把连接请求信息记录到等待队列。因此,connect函数返回后并不立即进行数据交换。
客户端的IP地址和端口是在调用connect函数时自动分配的。
三、回声服务端/客户端
1、linux
服务端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h> #define BUF_SIZE 1024
void error_handling(char * messages); int main(int argc, char *argv[])
{
if(argc != )
{
printf("Usage : %s <port>\n", argv[]);
exit();
}
int serverSock, clientSock;
struct sockaddr_in serverAddr, clientAddr;
socklen_t clientAddrSize; char message[BUF_SIZE];
int strLen; serverSock =socket(PF_INET, SOCK_STREAM, );
if(serverSock == -)
error_handling("socket() error"); memset(&serverAddr, , sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(atoi(argv[])); if(bind(serverSock, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == -)
error_handling("bind() error");
if(listen(serverSock, ) == -)
error_handling("listen() error"); puts("Server start...");
clientAddrSize = sizeof(clientAddr);
for(int i = ; i < ; i++){
clientSock = accept(serverSock, (struct sockaddr*) &clientAddr, &clientAddrSize);
if(clientSock == -)
error_handling("accept() error");
else
printf("Connected client %d\n", i+);
while((strLen=read(clientSock, message, BUF_SIZE)) != ){
puts("echo");
write(clientSock, message, strLen);
}
printf("Close client %d\n", i+);
close(clientSock);
} close(serverSock);
puts("Server close...");
return ;
} void error_handling(char * messages)
{
puts(messages);
exit();
}
客户端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h> #define BUF_SIZE 1024
void error_handling(char * messages); int main(int argc, char *argv[])
{
if(argc != )
{
printf("Usage : %s <IP> <port>\n", argv[]);
exit();
}
int sock;
struct sockaddr_in serv_addr;
char message[BUF_SIZE];
int strLen; sock = socket(PF_INET, SOCK_STREAM, );
if(sock == -)
error_handling("socket() error"); memset(&serv_addr, , sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[]);
serv_addr.sin_port = htons(atoi(argv[])); if(connect(sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -)
error_handling("connect() error");
else
puts("Connected...");
while(){
puts("Input message(Q to quit):");
fgets(message, BUF_SIZE, stdin);
if(!strcmp(message, "q\n") || !strcmp(message, "Q\n"))
break; strLen=strlen(message);
write(sock, message, strlen(message));
int recvLen = ;
while(recvLen < strLen){
int recvCnt = read(sock, &message[recvLen], BUF_SIZE-);
if(recvCnt == -)
error_handling("read() error");
recvLen+=recvCnt;
}
message[recvLen]=;
printf("Message from server: %s\n", message);
}
close(sock);
return ;
} void error_handling(char * messages)
{
puts(messages);
exit();
}
2、windows
服务端:
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h> #define BUF_SIZE 1024
void ErrorHandling(char *message); int main(int argc, char *argv[])
{
if (argc != ) {
printf("Usage : %s <port>\n", argv[]);
exit();
} WSADATA wsaData;
SOCKET serverSock, clientSock;
SOCKADDR_IN serverAddr, clientAddr;
int szClientAddr;
char message[BUF_SIZE];
int slen; if (WSAStartup(MAKEWORD(, ), &wsaData) != )
ErrorHandling("WSAStartup() error"); serverSock = socket(PF_INET, SOCK_STREAM, );
if (serverSock == INVALID_SOCKET)
ErrorHandling("socket() error");
memset(&serverAddr, , sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(atoi(argv[])); if (bind(serverSock, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
ErrorHandling("bind() error"); if (listen(serverSock, ) == SOCKET_ERROR)
ErrorHandling("listen() error");
for (int i = ; i < ; ++i) {
szClientAddr = sizeof(clientAddr);
clientSock = accept(serverSock, (SOCKADDR*)&clientAddr, &szClientAddr);
if (clientSock == INVALID_SOCKET)
ErrorHandling("accept() error");
else
printf("Connected client %d\n", i);
while ((slen =recv(clientSock, message, BUF_SIZE, )) != )
{
send(clientSock, message, slen, );
}
closesocket(clientSock);
printf("Closed client %d\n", i);
}
closesocket(serverSock);
WSACleanup();
return ;
} void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
}
客户端:
#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h> #define BUF_SIZE 1024
void ErrorHandling(char *message); int main(int argc, char* argv[]) {
if (argc != ) {
printf("Usage : %s <IP> <port>\n", argv[]);
exit();
} WSADATA wsaData;
SOCKET sock;
SOCKADDR_IN serverAddr;
char message[BUF_SIZE];
int sLen, recvLen; if (WSAStartup(MAKEWORD(, ), &wsaData) != )
ErrorHandling("WSAStartup() error"); sock = socket(PF_INET, SOCK_STREAM, );
if (sock == INVALID_SOCKET)
ErrorHandling("socket() error"); memset(&serverAddr, , sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(argv[]);
serverAddr.sin_port = htons(atoi(argv[])); if (connect(sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
ErrorHandling("connect() error");
else
printf("Connected.......\n");
while ()
{
fputs("Input message(Q to quit):", stdout);
fgets(message, BUF_SIZE, stdin);
if(!strcmp(message, "q\n") || !strcmp(message, "Q\n"))
break;
sLen = send(sock, message, strlen(message), );
recvLen = ;
while (recvLen < sLen) {
int cnt = recv(sock, message, BUF_SIZE - , );
if (cnt == -)
ErrorHandling("ercv() error");
recvLen += cnt;
}
message[recvLen] = ;
printf("Message from server: %s\n", message);
}
closesocket(sock);
WSACleanup();
return ;
} void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
}
回声TCP服务器端/客户端的更多相关文章
- python 网络编程(三)---TCP 服务器端客户端实现
客户端 客户端主要有4个步骤: 1)创建一个socket以连接服务器. socket = socket.socket(family, type),family参数代表地址家族,可为AF_INET(包括 ...
- 回声UDP服务器端/客户端
UDP是具有数据边界的协议,传输中调用I/O函数的次数非常重要.输入函数的调用次数要和输出函数的调用次数完全一致,这样才能保证接受全部已发送的数据. TCP套接字中需注册待传输数据的目标IP和端口,而 ...
- 【TCP/IP网络编程】:04基于TCP的服务器端/客户端
摘要:结合前面所讲述的知识,本篇文章主要介绍了简单服务器端和客户端实现的框架流程及相关函数接口. 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字(本 ...
- 【TCP/IP网络编程】:06基于UDP的服务器端/客户端
本篇文章简单描述了UDP传输协议的工作原理及特点. 理解UDP UDP和TCP一样同属于TCP/IP协议栈的第二层,即传输层. UDP套接字的特点 UDP的工作方式类似于传统的信件邮寄过程.寄信前应先 ...
- TCP服务器端和客户端程序设计【转】
本文转载自:http://blog.csdn.net/yueguanghaidao/article/details/7035248# 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.实验目的 ...
- 基于TCP的客户端、服务器端socket编程
一.实验目的 理解tcp传输客户端服务器端通信流程 二.实验平台 MAC OS 三.实验内容 编写TCP服务器套接字程序,程序运行时服务器等待客户的连接,一旦连接成功,则显示客户的IP地址.端口号,并 ...
- C/C++网络编程4——实现基于TCP的服务器端/客户端1
一.TCP服务器调用顺序: 调用socket函数创建套接字:声明并初始化地址信息结构体变量:调用bind函数向套接字分配地址:调用listen函数进入等待连接请求状态,只有调用了listen函数后客户 ...
- QT 使用QTcpServer QTcpSocket 建立TCP服务器端 和 客户端
1. 如图客户端连接server后,server发送"hello tcp" 给客户端 2. 实例代码 ----------------------------------- s ...
- Java基础知识强化之网络编程笔记09:TCP之客户端键盘录入服务器写到文本文件中
1. TCP之客户端键盘录入服务器写到文本文件中 (1)客户端: package cn.itcast_09; import java.io.BufferedReader; import java.io ...
随机推荐
- CentOS6.5下搭建ftp服务器(三种认证模式:匿名用户、本地用户、虚拟用户)
CentOS 6.5下搭建ftp服务器 vsftpd(very secure ftp daemon,非常安全的FTP守护进程)是一款运行在Linux操作系统上的FTP服务程序,不仅完全开源而且免费,此 ...
- DataGrip激活码
引言: 网上有有很多datagirp的激活码,但是经过尝试很多都失效了,找了半天终于 找到了一个可用的激活码! 1. 激活码 适用版本: DataGrip2018.2.3,2018.1.1,其他版本没 ...
- Java中String类型细节
Java中String类型细节 一 . String两种初始化方式 1 . String str1= “abc”;//String类特有的创建字符对象的方式,更高效 在字符串缓冲区中检测”abc”是否 ...
- SpringMVC获取页面表单参数的几种方式
以下几种方式只有在已搭好的SpringMVC环境中,才能执行成功! 首先,写一个登陆页面和一个Bean类 <%@ page language="java" co ...
- 华硕N55SF 折腾记
家里给老妈用的N55SL是2011年买的.这么多年了,最近一身毛病,最近来回折腾很多次.吐槽记录如下 1不定时花屏.闪屏,然后偶尔硬盘掉盘 (找不到硬盘,开机BIOS里).主要是使用一段时间之后发热, ...
- 牛客网NOIP赛前集训营-普及组(第一场)C 括号
括号 思路: dp 状态:dp[i][j]表示到i位置为止未匹配的 '(' 个数为j的方案数 状态转移: 如果s[i] == '(' dp[i][j] = dp[i-1][j] + dp[i-1][j ...
- POJ 3076 Sudoku
3076 思路: dfs + 剪枝 首先,如果这个位置只能填一种字母,那就直接填 其次,如果对于每一种字母,如果某一列或者某一行或者某一块只能填它,那就填它 然后,对于某个位置如果不能填字母了,或者某 ...
- Unity--- 纹理设置属性 alphaIsTransparency
官方的解释: 意思就是没什么实际效果,只是用做显示用. 参考:https://docs.unity3d.com/ScriptReference/Texture2D-alphaIsTransparenc ...
- Go语言学习之6 反射详解
1.反射: 定义: 反射就是程序能够在运行时检查变量和值,求出它们的类型. 可以在运行时动态获取变量的相关信息 Import ( ...
- Maven报错Please ensure you are using JDK 1.4 or above and not a JRE解决方法!
https://www.cnblogs.com/shihua513/p/6163682.html 在eclipse下用maven编译时,很有可能出现以下错误: Please ensure you ar ...