
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//TODO: 某些头文件
#define MAX_BUFFER 1024
void* thread_function(void* arg_array) {
int nr_bytes_read, class="superseo">char_index;
char receive_and_send_buffer[MAX_BUFFER],*p;
int* p_arg = (int*)arg_array;
int thread_session_socket = *p_arg;
printf("thread_session_socket = %d\n", thread_session_socket);
while (1) {
nr_bytes_read = read(thread_session_socket, receive_and_send_buffer, 1024);//TODO: 尝试从socket读取
if(nr_bytes_read == -1)//TODO: 如果错误,或没能从socket读取字符
break;
printf("Message from client(%d): %s\n", nr_bytes_read, receive_and_send_buffer);
for (p = receive_and_send_buffer; *p != ';'++ p)*
=p toupper (*)p;//TODO: 转换为大写 write
(,thread_session_socket, receive_and_send_buffer1024);//TODO: 返回给客户端 }
close
()thread_session_socket;//TODO: 关闭socketreturn
0 ;}
int
main (int, argcchar *[ argv]); {
socklen_t size_of_client_sockaddr;
pthread_t tidint
; listen_socketint
; session_socketint
; return_codeint
; port_numberstruct
sockaddr_in ; client_remote_sockaddrstruct
sockaddr_in ; server_local_sockaddr//服务器端运行时要给出端口信息,该端口为监听端口
if
( !=argc 2 )printf {
("Usage:%s port_number \n",[ argv0]);return
1 ;}
//获得输入的端口
=
port_number atoi ([argv1]);//创建套接字用于服务器的监听
=
listen_socket socket (,AF_INET, SOCK_STREAM0 );//TODO: socket()if
( ==listen_socket-1)//TODO: 如果出错 {perror
("ERR socket.");return
1 ;}
//填充关于服务器的套节字信息
memset
(&,server_local_sockaddr0 ,sizeof ()server_local_sockaddr);.
server_local_sockaddr=sin_family ; AF_INET.
server_local_sockaddr.sin_addr=s_addr htonl ()INADDR_ANY;.
server_local_sockaddr=sin_port htons ()port_number;//将服务器和套节字绑定
=
return_code bind (,listen_socket( structsockaddr * )&,server_local_sockaddrsizeof()server_local_sockaddr);//TODO: 调用bind绑定地址和端口(提供服务的位置)if
( ==return_code - 1)//TODO: 如果出错 {perror
("ERR bind.");close
()listen_socket;//TODO: 关闭监听socketreturn
1 ;}
//监听指定端口,连接5个客户端
=
return_code listen (,listen_socket5);//TODO: 请求监听、提供服务if
( ==return_code - 1)//TODO: 如果出错 {perror
("ERR listen.");close
()listen_socket;//TODO: 关闭监听socketreturn
1 ;}
//对每个连接来的客户端创建一个线程,单独与其进行通信。
//首先调用read函数读取客户端发送来的信息,将其转换成大写后发送回客户端,#退出。
while
( 1)= {
size_of_client_sockaddr sizeof ()client_remote_sockaddr;//TODO: 12345 改为自己的学号,此处不要修改write调用和STDOUT_FILENO参数!
write
(,STDOUT_FILENO"Listening & Accepting for 201930310132 ...\n" ,strlen ("Listening & Accepting for 201930310132 ...\n"));=
session_socket accept (,listen_socket( structsockaddr * )&,client_remote_sockaddr&)size_of_client_sockaddr;//TODO: 调用accept阻塞,接到客户机时返回 session_socketif
( ==session_socket - 1)//TODO: 如果出错 {if
( ==errno ) EINTRcontinue ;else
perror {
("ERR accept(): cannot accept client connect request");close
()listen_socket;//TODO: 关闭socketreturn
1 ;}
}
printf
("session_socket = %d\n",) session_socket;//打印建立连接的客户端产生的套节字 =
return_code pthread_create (&,tidNULL,,thread_function(void*)&)session_socket;//TODO: 调用 pthread_create,将 session_socket传递给 thread_functionif
( !=return_code 0 )//TODO: 如果出错 {perror
("ERR pthread_create()");close
()listen_socket;//TODO: 关闭一个socketclose
()session_socket;//TODO: 关闭另一个socketreturn
1 ;}
}
return
0 ;}
#
客户端
include#
include#
include#
include#
include#
include#
include#
include#
include #
include//TODO: 某些头文件
#
defineMAX_BUFFER 1024 int
main (int, argcchar *[ argv])int {
; local_socketint
; return_codechar
[ send_and_receive_buffer]MAX_BUFFER;int
; port_numberint
; nr_bytes_readstatic
struct sockaddr_in ; server_sockaddr//客户端运行需要给出具体的连接地址和端口
if
( !=argc 3 )printf {
("Usage: %s server_ip_address port_number \n",[ argv0]);return
1 ;}
//获得输入的端口
=
port_number atoi ([argv2]);//创建套节字用于客户端的连接
=
local_socket socket (,AF_INET, SOCK_STREAM0 );//TODO: 调用socketif
( ==local_socket - 1)//TODO: 如果错误 {perror
("ERR socket.");return
1 ;}
//填充关于服务器的套节字信息
memset
(&,server_sockaddr0 ,sizeof ()server_sockaddr);.
server_sockaddr=sin_family ; AF_INET.
server_sockaddr.sin_addr=s_addr inet_addr ([argv1]);.
server_sockaddr=sin_port htons ()port_number;//连接指定的服务器
=
return_code connect (,local_socket( structsockaddr *)&,server_sockaddrsizeof ()server_sockaddr);//TODO: 调用connectif
( ==return_code - 1)//TODO: 如果错误 {perror
("ERR connect.");close
()local_socket;return
1 ;}
memset
(,send_and_receive_buffer0 ,) MAX_BUFFER;//用户输入信息后,程序将输入的信息通过套接字发送给服务器 ,然后调用read函数从服务器中读取发送来的信息。
//输入“#”退出
while
( 1)//TODO: 12345 改为自己的学号,此处不要修改write调用和STDOUT_FILENO参数! {
write
(,STDOUT_FILENO"Type in a string for 201930310132:" ,strlen ("Type in a string for 201930310132:"));=
nr_bytes_read read (,STDIN_FILENO,send_and_receive_buffer1024);//TODO: 调用read, 从STDIN_FILENO读if
( 0nr_bytes_read > )write
(,local_socket, send_and_receive_buffer1024);//TODO: 调用write,写socket=
nr_bytes_read read (,local_socket, send_and_receive_buffer1024);//TODO: 调用read,读socketif
( 0nr_bytes_read > )printf
("Message form server: %s\n",) send_and_receive_buffer;if
( [send_and_receive_buffer0]== '#' )break
;}
close
()local_socket;return
0 ;}
简而言之,创建一个基本的socket还是比较简单的,过程可能有些繁琐。可以归纳为以下几步。
第一步:调用socket创建一个socket
第二步:调用bind函数绑定IP地址和端口号,绑定到 *** 作系统
第三步:调用listen开始转为可接收请求状态
第四步:调用accept函数受理连接请求
客户端需要一个connect函数来连接到服务器
利用write和read进行数据的读写 *** 作
关闭socket
再开启一个客户端,服务端会对每个连接来的客户端创建一个线程,单独与其进行通信。
https://blog.csdn.net/u014634338/article/details/48551755
https://blog.csdn.net/yanchuang1/article/details/48049259
https://blog.csdn.net/u011675745/article/details/78555250
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)