建议先去看一下思路

真的写的很不错呦~

思路参考博客:https://www.cnblogs.com/renfanzi/p/5713054.html

linux c语言socket编程代码(单一服务端与客户端) 【此代码有bug,但很方便理解,用于理解使用】:

代码参考博客:https://www.cnblogs.com/xudong-bupt/p/3483059.html

服务端代码:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h> #define MYPORT 8887
#define QUEUE 20
#define BUFFER_SIZE 1024 int main() {
// 实例化socket对象, 定义sockfd
/* AF_INET 默认为IPv4
* SOCK_STREAM 流式socket, for TCP
* 0 协议, 默认选择合适的协议
* */
int server_sockfd = socket(AF_INET, SOCK_STREAM, ); ///定义sockaddr_in
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(MYPORT);
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 将套接字绑定到地址
// bind,成功返回0,出错返回-1
if (bind(server_sockfd, (struct sockaddr *) &server_sockaddr, sizeof(server_sockaddr)) == -) {
perror("bind");
exit();
} // 监听
// listen,成功返回0,出错返回-1
if (listen(server_sockfd, QUEUE) == -) {
perror("listen");
exit();
} // 客户端套接字
char buffer[BUFFER_SIZE];
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr); // 进入阻塞状态,等待客户连接
// 成功返回非负描述字,出错返回-1
int conn = accept(server_sockfd, (struct sockaddr *) &client_addr, &length);
if (conn < ) {
perror("connect");
exit();
}
// 循环
while () {
memset(buffer, , sizeof(buffer));
// 接受消息
int len = recv(conn, buffer, sizeof(buffer), );
printf("len: %d\n", len);
//这里是一直循环的,如果客户端说一句话,然后结束以后,这里一直循环,需要注意 if (strcmp(buffer, "exit\n") == )
break;
fputs(buffer, stdout);
// 发送消息
send(conn, "hehe", , );
}
close(conn);
close(server_sockfd);
return ;
}

客户端代码:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h> #define MYPORT 8887
#define BUFFER_SIZE 1024 int main()
{
///定义sockfd
int sock_cli = socket(AF_INET,SOCK_STREAM, ); ///定义sockaddr_in
struct sockaddr_in servaddr;
memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MYPORT); ///服务器端口
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); ///服务器ip ///连接服务器,成功返回0,错误返回-1
if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < )
{
perror("connect");
exit();
} char sendbuf[BUFFER_SIZE];
char recvbuf[BUFFER_SIZE];
while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
{
send(sock_cli, sendbuf, strlen(sendbuf),); ///发送
if(strcmp(sendbuf,"exit\n")==)
break;
recv(sock_cli, recvbuf, sizeof(recvbuf),); ///接收
fputs(recvbuf, stdout); memset(sendbuf, , sizeof(sendbuf));
memset(recvbuf, , sizeof(recvbuf));
} close(sock_cli);
return ;
}

采用C/S架构,Tcp、Ip协议,服务器端使用共享内存的方式,不同客户端连接服务端,实现网络聊天室的功能(多用户)

服务端:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h> //数据类型定义
#include <sys/stat.h> //文件属性
#include <netinet/in.h> //定义数据结构sockaddr_in
#include <sys/socket.h> //提供socket函数和数据结构
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ipc.h>
#include <errno.h>
#include <sys/shm.h> //共享内存
#include <time.h>
#include<sys/time.h>
#include <arpa/inet.h> #define PERM S_IRUSR | S_IWUSR //用户读写
#define MYPORT 8080 //通信端口
#define BACKLOG 10 //定义服务器段可以连接的最大客户数
#define MYHOST "192.168.2.137"
#define WELCOME "|---------------Welcome to the chat room!----------------|"//当客户端连接服务端时,向客户端发送此字符串 //将int类型转换成char*类型
void itoa(int i, char *string) {
int mask = ;
while (i / mask >= )
mask *= ;
while (mask > ) {
*string++ = i / mask + '';
i %= mask;
mask /= ;
}
*string = '\0';
} //得到当前系统的时间
void get_cur_time(char *time_str) {
struct timeval now;
gettimeofday(&now, NULL);
strcpy(time_str, ctime(&now.tv_sec));
} //创建共享存储区
int shm_create() {
int shmid;
//shmid = shmget(IPC_PRIVATE, 1024, PERM);
if ((shmid = shmget(IPC_PRIVATE, , PERM)) == -) {
fprintf(stderr, "Create Share Memory Error:%s\n\a", strerror(errno));
exit();
}
return shmid;
} //端口绑定函数。创建套接字,并绑定到指定端口
int bindPort(unsigned short int port) {
int sockfd;
struct sockaddr_in my_addr;
sockfd = socket(AF_INET, SOCK_STREAM, ); //创建基于流套接字
//bzero(&(my_addr.sin_zero),0);
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET; //IPV4协议族
my_addr.sin_port = htons(port); //转换端口为网络字节序
my_addr.sin_addr.s_addr = inet_addr(MYHOST); if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -) {
perror("fail to bind");
exit();
} printf("bind success!\n");
return sockfd;
} int main(int argc, char *argv[]) {
int sockfd, clientfd; //监听套接字、客户套接字
int sin_size, recvbytes; pid_t pid, ppid; //定义父子进程标记
char *buf, *read_addr, *write_addr, *temp, *time_str; //需要用到的缓冲区
struct sockaddr_in their_addr; //定义地址结构
int shmid; shmid = shm_create(); //创建共享存储区 temp = (char *) malloc();
time_str = (char *) malloc();
sockfd = bindPort(MYPORT); //绑定端口 get_cur_time(time_str);
printf("Time is : %s\n", time_str); if (listen(sockfd, BACKLOG) == -) {
//在指定端口上监听
perror("fail to listen");
exit();
} printf("listen....\n");
while () {
/*
if (listen(sockfd, BACKLOG) == -1)
{
perror("fail to listen");
exit(1);
}
*/
//接受一个客户端的连接请求
if ((clientfd = accept(sockfd, (struct sockaddr *) &their_addr, &sin_size)) == -) {
perror("fail to accept");
exit();
} //得到客户端的IP地址输出
char address[];
inet_ntop(AF_INET, &their_addr.sin_addr, address, sizeof(address)); printf("accept from %s\n", address);
send(clientfd, WELCOME, strlen(WELCOME), ); //发送问候信息
buf = (char *) malloc(); ppid = fork(); //创建子进程
if (ppid == ) //子进程
{
pid = fork(); //子进程创建子进程
while () {
if (pid > ) {
//buf = (char *)malloc(255);
//父进程用于接收信息
memset(buf, , );
printf("OK\n");
if ((recvbytes = recv(clientfd, buf, , )) <= ) {
perror("fail to recv");
close(clientfd);
raise(SIGKILL);
exit();
}
write_addr = shmat(shmid, , ); //shmat将shmid所代表的全局的共享存储区关联到本进程的进程空间
memset(write_addr, '\0', ); //把接收到的消息存入共享存储区中
strncpy(write_addr, buf, ); //把接收到的消息连接此刻的时间字符串输出到标准输出
get_cur_time(time_str);
strcat(buf, time_str);
printf(" %s\n", buf);
} else if (pid == ) {
//子进程用于发送消息
sleep(); //子进程先等待父进程把接收到的信息存入共享存储区
read_addr = shmat(shmid, , ); //读取共享存储区的内容 //temp存储上次读取过的内容,每次先判断是否已经读取过该消息
if (strcmp(temp, read_addr) != ) {
strcpy(temp, read_addr); //更新temp,表示已经读取过该消息 get_cur_time(time_str);
strcat(read_addr, time_str);
if (send(clientfd, read_addr, strlen(read_addr), ) == -) {
perror("fail to send");
exit();
}
memset(read_addr, '\0', );
strcpy(read_addr, temp);
}
} else
perror("fai to fork");
}
}
}
printf("------------------------------------\n");
free(buf);
close(sockfd);
close(clientfd);
return ;
}

客户端二、客户端三...

#include <stdio.h>
#include <netinet/in.h> //定义数据结构sockaddr_in
#include <sys/socket.h> //定义socket函数以及数据结构
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <netinet/in.h>
#include <arpa/inet.h> #define MYPORT 8080
#define MYHOST "192.168.2.137" int main(int argc, char *argv[])
{
struct sockaddr_in clientaddr; //定义地址结构
pid_t pid;
int clientfd, sendbytes, recvbytes;
struct hostent *host; //主机信息数据结构
char *buf, *buf_read;
// if (argc < 4)
// {
// printf("wrong usage");
// printf("%s host port name\n", argv[0]);
// exit(1);
// }
// host = gethostbyname(argv[1]);
if ((clientfd = socket(AF_INET, SOCK_STREAM, )) == -)
{
perror("fail to create socket");
exit();
}
bzero(&clientaddr, sizeof(clientaddr));
clientaddr.sin_family = AF_INET;
clientaddr.sin_port = htons(MYPORT);
clientaddr.sin_addr.s_addr = inet_addr(MYHOST);
//客户端连接服务端
if (connect(clientfd, (struct sockaddr *)&clientaddr, sizeof(struct sockaddr)) == -)
{
perror("fail to connect");
exit();
}
buf = (char *)malloc();
memset(buf, , );
buf_read = (char *)malloc(); if (recv(clientfd, buf, , ) == -)
{
perror("fail to recv");
exit();
}
printf("\n%s\n", buf);
pid = fork();
while ()
{
if (pid > )
{
//父进程发送消息
strcpy(buf, "afsasdf");
strcat(buf, ":");
memset(buf_read, , );
fgets(buf_read, , stdin);
strncat(buf, buf_read, strlen(buf_read) - );
if ((sendbytes = send(clientfd, buf, strlen(buf), )) == -)
{
perror("fail to send");
exit();
}
}
else if (pid == )
{
//子进程接受消息
memset(buf, , );
if (recv(clientfd, buf, , ) <= )
{
perror("fail to recv");
close(clientfd);
raise(SIGSTOP);
exit();
}
printf("%s\n", buf);
}
else
perror("fork error");
}
close(clientfd);
return ;
}

C语言socket编程的更多相关文章

  1. 计算机网络|C语言Socket编程,实现两个程序间的通信

    C语言Socket编程,实现两个程序间的通信 server和client通信流程图 在mooc上找到的,使用Socket客户端client和服务端server通信的流程图

  2. [转]C语言SOCKET编程指南

    1.介绍 Socket编程让你沮丧吗?从man pages中很难得到有用的信息吗?你想跟上时代去编Internet相关的程序,但是为你在调用 connect() 前的bind() 的结构而不知所措?等 ...

  3. C语言SOCKET编程指南

    1.介绍 Socket 编程让你沮丧吗?从man pages中很难得到有用的信息吗?你想跟上时代去编Internet相关的程序,但是为你在调用 connect() 前的bind() 的结构而不知所措? ...

  4. 多种语言socket编程集锦—win32

    原文 http://www.blogjava.net/huyi2006/articles/263831.html 借此地方整理以下socket编程的多种语言的实现,socket可以跨平台的通信,因此多 ...

  5. C语言socket编程--每日签到

    前几天写了个python的每日签到,你运行还得借助crontab,很是不爽.....正好前几天看了个关于c编写daemon进程,加上自己那点可怜的socket知识,于是我们重操旧页,C语言版的每日签到 ...

  6. C语言Socket编程(计算机网络作业)

    最近我计算机网络课程要做作业了,没办法跟着老师一步一步的写C语言的代码,使用的计算就是Socket通信发送消息:代码实现的功能很简单,客户端向服务器端发送消息,服务器端接收客户端发来的消息,并且输出显 ...

  7. C语言socket编程——linux环境

    先写一个服务器端的监听程序,功能室从客户端读取字符,接收到后告知客户端“I got your message: ”+收到的消息:server.c #include <stdio.h> #i ...

  8. C语言socket编程----实现UDP通信

    TCP/IP协议叫做传输控制/网际协议,又叫做网络通信协议.实际上,它包括上百个功能的协议. 套接字(socket):在网络中用来描述计算机中不同程序与其他计算程序的通信方式. 套接字分为三类; 流式 ...

  9. C语言socket编程----struct sockaddr 和struct sockaddr_in介绍和初始化

    sockaddr结构体 struct  sockaddr{ sa_family_t  sa_family; //地址族,最常用的是"AF_INET"(IPV4)和"AF_ ...

随机推荐

  1. tomcat端口被占用的问题

    在dos下,输入  netstat   -ano|findstr  8080  //说明:查看占用8080端口的进程 显示占用端口的进程 taskkill  /pid  6856  /f  //说明, ...

  2. BZOJ2319 : 黑白棋游戏

    将01串按1分段,那么分析可得长度为$a$的段拼上长度为$b$的段的SG值为$a-[a\leq b]$. 设$f[i][j][k][l]$表示从后往前用了$i$个1,$j$个0,当前段长度为$k$,后 ...

  3. UltraEdit使用(工具类似于notepad++)

    打开多个文件,在多个文件中切换,鼠标点/ Ctrl+Tab自动换行的设置: 高级-->配置-->编辑器-->自动换行,制表符设置-->默认为每个文件启用自动换行 去掉自动备份设 ...

  4. Hibernate(12)_基于主键的双向1对1

    一.基于主键的双向1对1 1.介绍: 基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据"对方"的主键来生成自己的主键,自己并不能独立生成主键. <p ...

  5. 微信小程序中遮罩层的滚动穿透问题

    如果弹出层没有滚动事件: <view wx:if="{{alert}}" catchtouchmove="myCatchTouch"> <te ...

  6. spring跨域问题

    import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Co ...

  7. 倾斜摄影数据OSGB进入到ArcGIS平台相关问题小结

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/zglybl/article/details/75252288      随着倾斜摄影技术的发展,大家 ...

  8. 近期 Unity 提交苹果审核被拒的问题

    游戏提交苹果审核,被打回.在 bugly 上没有查到崩溃信息,苹果给了 crash 日志也说明. 拒绝原因如下: Your app crashed on iPad or iPhone running ...

  9. LSTM Networks

    Understanding LSTM Networks Recurrent Neural Networks Humans don’t start their thinking from scratch ...

  10. Gitbook 简介 使用总结 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...